diff --git a/Makefile.am b/Makefile.am
index e04fbfc76..f12f2a24f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1011,6 +1011,7 @@ libconf_a_SOURCES = \
 	src/config/Parser.cxx src/config/Parser.hxx \
 	src/config/Global.cxx src/config/Global.hxx \
 	src/config/File.cxx src/config/File.hxx \
+	src/config/Migrate.cxx src/config/Migrate.hxx \
 	src/config/Templates.cxx src/config/Templates.hxx \
 	src/config/Domain.cxx src/config/Domain.hxx \
 	src/config/Option.hxx
diff --git a/src/config/Data.cxx b/src/config/Data.cxx
index cd43e7cff..f8518aa3d 100644
--- a/src/config/Data.cxx
+++ b/src/config/Data.cxx
@@ -180,3 +180,18 @@ ConfigData::FindBlock(ConfigBlockOption option,
 
 	return nullptr;
 }
+
+ConfigBlock &
+ConfigData::MakeBlock(ConfigBlockOption option,
+		      const char *key, const char *value)
+{
+	auto *block = const_cast<ConfigBlock *>(FindBlock(option, key, value));
+	if (block == nullptr) {
+		auto new_block = std::make_unique<ConfigBlock>();
+		new_block->AddBlockParam(key, value);
+		block = new_block.get();
+		AddBlock(option, std::move(new_block));
+	}
+
+	return *block;
+}
diff --git a/src/config/Data.hxx b/src/config/Data.hxx
index 65ec0af84..d58948489 100644
--- a/src/config/Data.hxx
+++ b/src/config/Data.hxx
@@ -101,6 +101,9 @@ struct ConfigData {
 	gcc_pure
 	const ConfigBlock *FindBlock(ConfigBlockOption option,
 				     const char *key, const char *value) const;
+
+	ConfigBlock &MakeBlock(ConfigBlockOption option,
+				     const char *key, const char *value);
 };
 
 #endif
diff --git a/src/config/Global.cxx b/src/config/Global.cxx
index 62c7eb159..fceb5b603 100644
--- a/src/config/Global.cxx
+++ b/src/config/Global.cxx
@@ -19,6 +19,7 @@
 
 #include "config.h"
 #include "Global.hxx"
+#include "Migrate.hxx"
 #include "Data.hxx"
 #include "Block.hxx"
 #include "File.hxx"
@@ -48,7 +49,8 @@ GetGlobalConfig() noexcept
 void
 ReadConfigFile(Path path)
 {
-	return ReadConfigFile(config_data, path);
+	ReadConfigFile(config_data, path);
+	Migrate(config_data);
 }
 
 static void
diff --git a/src/config/Migrate.cxx b/src/config/Migrate.cxx
new file mode 100644
index 000000000..9c1ebf7df
--- /dev/null
+++ b/src/config/Migrate.cxx
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2003-2018 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "Migrate.hxx"
+#include "Data.hxx"
+#include "Block.hxx"
+
+static void
+MigrateParamToBlockParam(ConfigData &config, ConfigOption old_option,
+			 ConfigBlockOption new_block_option,
+			 const char *block_id_key, const char *block_id_value,
+			 const char *block_value_key) noexcept
+{
+	const auto *param = config.GetParam(old_option);
+	if (param == nullptr)
+		return;
+
+	auto &block = config.MakeBlock(new_block_option,
+				       block_id_key, block_id_value);
+	if (block.GetBlockParam(block_value_key) == nullptr)
+		block.AddBlockParam(block_value_key, param->value,
+				     param->line);
+}
+
+static void
+MigrateCurlProxyConfig(ConfigData &config) noexcept
+{
+	MigrateParamToBlockParam(config, ConfigOption::HTTP_PROXY_HOST,
+				 ConfigBlockOption::INPUT, "plugin", "curl",
+				 "proxy");
+	MigrateParamToBlockParam(config, ConfigOption::HTTP_PROXY_PORT,
+				 ConfigBlockOption::INPUT, "plugin", "curl",
+				 "proxy_port");
+	MigrateParamToBlockParam(config, ConfigOption::HTTP_PROXY_USER,
+				 ConfigBlockOption::INPUT, "plugin", "curl",
+				 "proxy_user");
+	MigrateParamToBlockParam(config, ConfigOption::HTTP_PROXY_PASSWORD,
+				 ConfigBlockOption::INPUT, "plugin", "curl",
+				 "proxy_password");
+}
+
+void
+Migrate(ConfigData &config) noexcept
+{
+	MigrateCurlProxyConfig(config);
+}
diff --git a/src/config/Migrate.hxx b/src/config/Migrate.hxx
new file mode 100644
index 000000000..6c0774386
--- /dev/null
+++ b/src/config/Migrate.hxx
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003-2018 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_CONFIG_MIGRATE_HXX
+#define MPD_CONFIG_MIGRATE_HXX
+
+struct ConfigData;
+
+/**
+ * Migrate deprecated #Config settings to new-style settings.
+ */
+void
+Migrate(ConfigData &config) noexcept;
+
+#endif
diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx
index a4ccc8310..b3832c673 100644
--- a/src/input/plugins/CurlInputPlugin.cxx
+++ b/src/input/plugins/CurlInputPlugin.cxx
@@ -31,7 +31,6 @@
 #include "../IcyInputStream.hxx"
 #include "IcyMetaDataParser.hxx"
 #include "../InputPlugin.hxx"
-#include "config/Global.hxx"
 #include "config/Block.hxx"
 #include "tag/Builder.hxx"
 #include "tag/Tag.hxx"
@@ -328,15 +327,6 @@ input_curl_init(EventLoop &event_loop, const ConfigBlock &block)
 	proxy_user = block.GetBlockValue("proxy_user");
 	proxy_password = block.GetBlockValue("proxy_password");
 
-	if (proxy == nullptr) {
-		/* deprecated proxy configuration */
-		proxy = config_get_string(ConfigOption::HTTP_PROXY_HOST);
-		proxy_port = config_get_positive(ConfigOption::HTTP_PROXY_PORT, 0);
-		proxy_user = config_get_string(ConfigOption::HTTP_PROXY_USER);
-		proxy_password = config_get_string(ConfigOption::HTTP_PROXY_PASSWORD,
-						   "");
-	}
-
 	verify_peer = block.GetBlockValue("verify_peer", true);
 	verify_host = block.GetBlockValue("verify_host", true);
 }
diff --git a/test/run_filter.cxx b/test/run_filter.cxx
index fef36b4c0..47e61a2ca 100644
--- a/test/run_filter.cxx
+++ b/test/run_filter.cxx
@@ -21,6 +21,7 @@
 #include "config/Param.hxx"
 #include "config/Data.hxx"
 #include "config/File.hxx"
+#include "config/Migrate.hxx"
 #include "fs/Path.hxx"
 #include "AudioParser.hxx"
 #include "AudioFormat.hxx"
@@ -79,6 +80,7 @@ try {
 
 	ConfigData config;
 	ReadConfigFile(config, config_path);
+	Migrate(config);
 
 	/* parse the audio format */
 
diff --git a/test/run_output.cxx b/test/run_output.cxx
index 9f9c5c1c6..fbfd57947 100644
--- a/test/run_output.cxx
+++ b/test/run_output.cxx
@@ -24,6 +24,7 @@
 #include "config/Param.hxx"
 #include "config/Data.hxx"
 #include "config/File.hxx"
+#include "config/Migrate.hxx"
 #include "config/Option.hxx"
 #include "config/Block.hxx"
 #include "event/Thread.hxx"
@@ -124,6 +125,7 @@ try {
 
 	ConfigData config;
 	ReadConfigFile(config, config_path);
+	Migrate(config);
 
 	EventThread io_thread;
 	io_thread.Start();