The configuration system (CS) in Drupal 8 is an indispensable tool, however this article is not meant as an introduction to the CS because that ground has already been covered by others. If you’re new to CS, this article will get you up to speed on what it is and why you might find it useful:

Alright, if you’re reading past this point, I will assume you have a baseline understanding of what the CS is; now to the fun part.

    Common CS Pitfalls:

    UUID Mismatch

    The CS is meant to move configuration between different versions of the same site. The way that Drupal distinguishes one site from another is through a Universally Unique Identifier (UUID). The UUID of the configuration that you import (found in must match the UUID stored in the row of the config table in your target database. If it doesn’t, your import will fail with the following message: “Site UUID in source storage does not match the target storage.”

    There are ways around this (which we’ll cover below), but for most standard use cases this means that you should instantiate a new version of your site (think dev — test — prod) from a database dump of your pre-existing site. As long as you do that, your UUID’s will match and happiness will ensue.

    Configuration vs Content Grey Areas

    There are four broad categories of data in Drupal 8: State, Session, Configuration and Content. As the name suggests, the CS is designed to only manage configuration. This can lead to confusion in cases where it is not immediately clear that what you’re attempting to export is a blend of configuration and content. For instance, this can happen when you attempt to export a custom block. The problem here is that what you’re trying to export is part configuration and part content. Block placement (where it goes within a theme) is configuration, however the content of the block itself is content, which can’t be managed via the CS. If you’re not aware of this, you will get the broken block handler (“This block is broken or missing. You may be missing content or you might need to enable the original module.”) after deploying the block placement from the source environment to the target environment without the corresponding block content existing on the target environment beforehand.

    Tips & Tricks:

    Change location of config_sync directory

    When you install Drupal, it will create a config sync directory for you at a path like this:


    The idea here is that your config sync directory could contain sensitive information, so putting it in a directory that is specific to each site and hard to guess makes sense from a security perspective. However, you can do one better by placing your config sync directory somewhere outside of your webroot, preventing it from ever being served by your webserver. You can do that in settings.php like so:

    $config_directories = array(CONFIG_SYNC_DIRECTORY => '../config/sync');

    Non destructive configuration imports

    By default, configuration synchronization is an all or nothing process. You take the data in your sync directory and place it in the config table of your database, overwriting anything that was there previously (and vice versa). If you want to avoid being quite so absolute, you can use the — partial flag when importing configuration via drush (drush config-import — partial). This will allow you to import new configuration items, update existing ones, and prevent you from deleting configuration items in the database that are not yet stored in the sync directory.

    Environment Specific Configuration

    If you’re interested in storing different configuration items for different environments, the configuration split module has you covered. It allows you to set up split directories where you can store environment specific configuration items. For instance, you might want different performance settings locally than in production. Of course you could override these settings in a settings.local.php file, but configuration split can do the same thing in a more graceful manner.

    There are already some great articles on how to set up configuration split, so I won’t duplicate those efforts here. Check out these articles for more detail:

    Before we move on I do want to clarify some of the terminology used by the module as it can be confusing. When setting up a configuration split, you have the option to add configuration items to the blacklist, or to the greylist. The difference between these two lists is subtle but important.

    • Blacklist: Configuration items that are explicitly managed by the split in question. These configuration items will be removed from the default directory. You can now store that configuration item in one or more configuration split, but not in the default directory.
    • Greylist: Configuration items on the grey list are not automatically removed from the default configuration directory. If a configuration item exists in the currently active split, it takes precedence over the copy stored in the default directory. If a copy of the greylisted configuration item does not exist in the currently active split, the configuration item from the default directory is used.

    For example, if you want to override site performance settings in your local split in order to disable css / js aggregation, the greylist would be a good option. This would allow you to store your performance settings for dev / test / prod in the default directory, while also storing an altered version for local development in your local split. You can also achieve this using the blacklist, but you would need to store a copy of the performance settings in each split. If performance settings are the same for dev / test / prod and only vary for the local split, this is duplicative.

    Importing Configuration From Another Site

    As I mentioned above, mismatching UUID’s will prevent you from importing configuration from a different site. However, there are (at least) three ways around this.

    Other useful configuration modules