diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php
index c025a2079a6e5b373d9a82d3db86d12b9244cbf7..d775cc2d30ea6be8460a8d37b9e02769d3bfca5c 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManager.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php
@@ -81,7 +81,8 @@ public function buildDataDefinition(array $definition, $value, $name = NULL, $pa
     // Add default values for data type and replace variables.
     $definition += array('type' => 'undefined');
 
-    if (strpos($definition['type'], ']')) {
+    $type = $definition['type'];
+    if (strpos($type, ']')) {
       // Replace variable names in definition.
       $replace = is_array($value) ? $value : array();
       if (isset($parent)) {
@@ -90,10 +91,13 @@ public function buildDataDefinition(array $definition, $value, $name = NULL, $pa
       if (isset($name)) {
         $replace['%key'] = $name;
       }
-      $definition['type'] = $this->replaceName($definition['type'], $replace);
+      $type = $this->replaceName($type, $replace);
+      // Remove the type from the definition so that it is replaced with the
+      // concrete type from schema definitions.
+      unset($definition['type']);
     }
     // Add default values from type definition.
-    $definition += $this->getDefinition($definition['type']);
+    $definition += $this->getDefinition($type);
 
     $data_definition = $this->createDataDefinition($definition['type']);
 
@@ -147,15 +151,16 @@ public function clearCachedDefinitions() {
   }
 
   /**
-   * Gets fallback metadata name.
+   * Gets fallback configuration schema name.
    *
    * @param string $name
    *   Configuration name or key.
    *
    * @return null|string
-   *   Same name with the last part(s) replaced by the filesystem marker.
-   *   for example, breakpoint.breakpoint.module.toolbar.narrow check for
-   *   definition in below order:
+   *   The resolved schema name for the given configuration name or key. Returns
+   *   null if there is no schema name to fallback to. For example,
+   *   breakpoint.breakpoint.module.toolbar.narrow will check for definitions in
+   *   the following order:
    *     breakpoint.breakpoint.module.toolbar.*
    *     breakpoint.breakpoint.module.*.*
    *     breakpoint.breakpoint.module.*
@@ -163,12 +168,19 @@ public function clearCachedDefinitions() {
    *     breakpoint.breakpoint.*
    *     breakpoint.*.*.*.*
    *     breakpoint.*
-   *   Returns null, if no matching element.
+   *   Colons are also used, for example,
+   *   block.settings.system_menu_block:footer will check for definitions in the
+   *   following order:
+   *     block.settings.system_menu_block:*
+   *     block.settings.*:*
+   *     block.settings.*
+   *     block.*.*:*
+   *     block.*
    */
   protected function getFallbackName($name) {
     // Check for definition of $name with filesystem marker.
-    $replaced = preg_replace('/(\.[^\.]+)([\.\*]*)$/', '.*\2', $name);
-    if ($replaced != $name ) {
+    $replaced = preg_replace('/([^\.:]+)([\.:\*]*)$/', '*\2', $name);
+    if ($replaced != $name) {
       if (isset($this->definitions[$replaced])) {
         return $replaced;
       }
@@ -177,7 +189,7 @@ protected function getFallbackName($name) {
         // wildcard to see if there is a greedy match. For example,
         // breakpoint.breakpoint.*.* becomes
         // breakpoint.breakpoint.*
-        $one_star = preg_replace('/\.([\.\*]*)$/', '.*', $replaced);
+        $one_star = preg_replace('/\.([:\.\*]*)$/', '.*', $replaced);
         if ($one_star != $replaced && isset($this->definitions[$one_star])) {
           return $one_star;
         }
diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php
index 7401247700dd7ec7146e5c52bf6c176d2596f014..4e810b5c8255e5016e91baed9a445b9a464bc36f 100644
--- a/core/modules/config/src/Tests/ConfigSchemaTest.php
+++ b/core/modules/config/src/Tests/ConfigSchemaTest.php
@@ -397,4 +397,37 @@ function testSchemaFallback() {
     $this->assertIdentical($definition, $definition2);
   }
 
+  /**
+   * Tests use of colons in schema type determination.
+   *
+   * @see \Drupal\Core\Config\TypedConfigManager::getFallbackName()
+   */
+  function testColonsInSchemaTypeDetermination() {
+    $tests = \Drupal::service('config.typed')->get('config_schema_test.plugin_types')->get('tests');
+    $definition = $tests[0]->getDataDefinition()->toArray();
+    $this->assertEqual($definition['type'], 'test.plugin_types.boolean');
+
+    $definition = $tests[1]->getDataDefinition()->toArray();
+    $this->assertEqual($definition['type'], 'test.plugin_types.boolean:*');
+
+    $definition = $tests[2]->getDataDefinition()->toArray();
+    $this->assertEqual($definition['type'], 'test.plugin_types.*');
+
+    $definition = $tests[3]->getDataDefinition()->toArray();
+    $this->assertEqual($definition['type'], 'test.plugin_types.*');
+
+    $tests = \Drupal::service('config.typed')->get('config_schema_test.plugin_types')->get('test_with_parents');
+    $definition = $tests[0]['settings']->getDataDefinition()->toArray();
+    $this->assertEqual($definition['type'], 'test_with_parents.plugin_types.boolean');
+
+    $definition = $tests[1]['settings']->getDataDefinition()->toArray();
+    $this->assertEqual($definition['type'], 'test_with_parents.plugin_types.boolean:*');
+
+    $definition = $tests[2]['settings']->getDataDefinition()->toArray();
+    $this->assertEqual($definition['type'], 'test_with_parents.plugin_types.*');
+
+    $definition = $tests[3]['settings']->getDataDefinition()->toArray();
+    $this->assertEqual($definition['type'], 'test_with_parents.plugin_types.*');
+  }
+
 }
diff --git a/core/modules/config/tests/config_schema_test/config/install/config_schema_test.plugin_types.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.plugin_types.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ab06fba962338403b0f21fb32dc102e5ad201abd
--- /dev/null
+++ b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.plugin_types.yml
@@ -0,0 +1,30 @@
+tests:
+  -
+    plugin_id: boolean
+    value: TRUE
+  -
+    plugin_id: boolean:derivative
+    value: TRUE
+  -
+    plugin_id: string
+    value: 'Foo'
+  -
+    plugin_id: string:derivative
+    value: 'Foo'
+test_with_parents:
+  -
+    plugin_id: boolean
+    settings:
+      value: TRUE
+  -
+    plugin_id: boolean:derivative
+    settings:
+      value: TRUE
+  -
+    plugin_id: string
+    settings:
+      value: 'Foo'
+  -
+    plugin_id: string:derivative
+    settings:
+      value: 'Foo'
diff --git a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
index 34c6089af7f582e94ce73344b03f6714b8a67749..cbc3c6190023dc8bb1afdaf828f93a5d3d1541f9 100644
--- a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
+++ b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
@@ -149,3 +149,61 @@ config_schema_test.ignore:
     weight:
       type: integer
       label: 'Weight'
+
+config_schema_test.plugin_types:
+  type: mapping
+  mapping:
+    tests:
+      type: sequence
+      sequence:
+        - type: test.plugin_types.[plugin_id]
+    test_with_parents:
+      type: sequence
+      sequence:
+        - type: mapping
+          mapping:
+            plugin_id:
+              type: string
+            settings:
+              type: test_with_parents.plugin_types.[%parent.plugin_id]
+
+test.plugin_types:
+  type: mapping
+  mapping:
+    plugin_id:
+      type: string
+
+test.plugin_types.boolean:
+  type: mapping
+  mapping:
+    plugin_id:
+      type: string
+    value:
+      type: boolean
+
+test.plugin_types.boolean:*:
+  type: test.plugin_types.boolean
+
+test_with_parents.plugin_types.boolean:
+  type: mapping
+  mapping:
+    value:
+      type: boolean
+
+test_with_parents.plugin_types.boolean:*:
+  type: test_with_parents.plugin_types.boolean
+
+test.plugin_types.*:
+  type: mapping
+  mapping:
+    plugin_id:
+      type: string
+    value:
+      type: string
+
+test_with_parents.plugin_types.*:
+  type: mapping
+  mapping:
+    value:
+      type: string
+