diff --git a/src/config/ArcanistConfigurationEngine.php b/src/config/ArcanistConfigurationEngine.php
--- a/src/config/ArcanistConfigurationEngine.php
+++ b/src/config/ArcanistConfigurationEngine.php
@@ -178,6 +178,22 @@
     ArcanistConfigurationEngineExtension $extension,
     $is_alias_of = null) {
 
+    $reserved = array(
+      // The presence of this key is used to detect old "~/.arcrc" files, so
+      // configuration options may not use it.
+      'config',
+    );
+    $reserved = array_fuse($reserved);
+
+    if (isset($reserved[$key])) {
+      throw new Exception(
+        pht(
+          'Extension ("%s") defines invalid configuration with key "%s". '.
+          'This key is reserved.',
+          get_class($extension),
+          $key));
+    }
+
     $is_ok = preg_match('(^[a-z][a-z0-9._-]{2,}\z)', $key);
     if (!$is_ok) {
       if ($is_alias_of === null) {
diff --git a/src/config/source/ArcanistFilesystemConfigurationSource.php b/src/config/source/ArcanistFilesystemConfigurationSource.php
--- a/src/config/source/ArcanistFilesystemConfigurationSource.php
+++ b/src/config/source/ArcanistFilesystemConfigurationSource.php
@@ -16,6 +16,8 @@
       }
     }
 
+    $values = $this->didReadFilesystemValues($values);
+
     parent::__construct($values);
   }
 
@@ -29,4 +31,8 @@
 
   abstract public function getFileKindDisplayName();
 
+  protected function didReadFilesystemValues(array $values) {
+    return $values;
+  }
+
 }
\ No newline at end of file
diff --git a/src/config/source/ArcanistUserConfigurationSource.php b/src/config/source/ArcanistUserConfigurationSource.php
--- a/src/config/source/ArcanistUserConfigurationSource.php
+++ b/src/config/source/ArcanistUserConfigurationSource.php
@@ -7,4 +7,42 @@
     return pht('User Config File');
   }
 
+  public function didReadFilesystemValues(array $values) {
+    // Before toolsets, the "~/.arcrc" file had separate top-level keys for
+    // "config", "hosts", and "aliases". Transform this older file format into
+    // a more modern format.
+
+    if (!isset($values['config'])) {
+      // This isn't an older file, so just return the values unmodified.
+      return $values;
+    }
+
+    // Make the keys in "config" top-level keys. Then add in whatever other
+    // top level keys exist, other than "config", preferring keys that already
+    // exist in the "config" dictionary.
+
+    // For example, this older configuration file:
+    //
+    //  {
+    //     "hosts": ...,
+    //     "config": {x: ..., y: ...},
+    //     "aliases": ...
+    //   }
+    //
+    // ...becomes this modern file:
+    //
+    //  {
+    //    "x": ...,
+    //    "y": ...,
+    //    "hosts": ...,
+    //    "aliases": ...
+    //  }
+
+    $result = $values['config'];
+    unset($values['config']);
+    $result += $values;
+
+    return $result;
+  }
+
 }
\ No newline at end of file