3.0.0's domain_config_update_10001() dispatches to \Drupal\domain_config\Service\DomainConfigMigration::migrateDomainConfiguration(). The legacy-name parser uses this regex:

$pattern = '/^domain\.config\.' . $domain_id . '(?:\.([a-z]{2}))?\.([^.]+\.[^.]+)$/';

Two narrow captures silently drop legacy 2.x rows:

base segments langcode matches?
2 none yes
2 2-letter yes
2 3-letter (fil) or hyphenated (pt-br, zh-hans, nb-no) no
3+ any no

Skipped rows are not deleted by cleanupLegacyConfigurations() (it only deletes rows that matched the regex), so the data is still on disk in the unpurged 2.x default storage — just invisible to the 3.x runtime. The matching gap also affects domain_config_ui.settings.overridable_configurations, which the migration writes to inside the loop: it picks up only the rows that matched.

Most visible casualty: system.theme.global (3-segment base name, served by SystemThemeSettingsForm extends ConfigFormBase which exposed the domain_config_ui toggle in 2.x). Sites using uncommon langcodes (pt-br, etc.) are also affected.

Proposed fix (3.0.x)

Patch DomainConfigMigration::migrateDomainConfiguration() to use the same prefix-strip + installed-langcode-list approach MR !379 introduced for 3.x's DomainConfigOverrideMigration:

  • strip the domain.config.{domain_id}. prefix, then split the payload on the first dot;
  • treat the first segment as a langcode iff it matches BCP47 shape AND is in the installed-languages list — otherwise treat it as part of the config name;
  • everything else is the config name (3+ segments are fine);
  • guard each $collection->write($name, $data) with $collection->exists($name) to avoid stomping a value the admin re-set through the UI in the meantime;
  • track conflicts in the result array and surface them in the update message + watchdog.

No new _update_10002. The patch is silent; new 2.x → 3.0.1+ migrations work correctly out of the box on first run.

Recovery for existing 3.0.0 sites

Sites already at schema = 10001 with stranded legacy rows have two paths:

  1. Re-run _update_10001 by resetting the schema:
    drush php:eval '\Drupal::keyValue("system.schema")->set("domain_config", 10000);'
    drush updatedb

    The patched service runs against the leftover legacy rows. The matched-and-migrated-on-the-first-run rows were already delete()-d by cleanupLegacyConfigurations(), so listAll() returns only the previously-skipped rows. The exists() guard protects against stomping any UI overrides set since the first migration. overridable_configurations is mutated in place additively, existing entries preserved.

  2. Wait for 3.1.x. 3.x's domain_config_update_10002() auto-installs domain_config_language and runs DomainConfigOverrideMigration::migrateConfigurations() against the same legacy rows; the stranded rows are picked up at that point. Collection-name strings are byte-identical across branches (domain.{domain_id}, domain.{domain_id}.language.{langcode}), so a site that upgraded directly 3.0.x → 3.1.x without running the recovery lands at the same end state, just later.

Suggested CHANGELOG note for 3.0.1

"Fixed silent skipping of legacy 2.x domain config rows with hyphenated/3-letter langcodes (pt-br, fil, …) or with 3+ segment base config names (system.theme.global, system.image.gd, …) during the 2.x → 3.x migration. Sites that updated to 3.0.0 with overrides of those shapes can recover by resetting the domain_config schema to 10000 and re-running drush updatedb; the legacy rows are still on disk and will be picked up by the patched migration. Sites updating directly from 2.x to 3.0.1+ are not affected."

Tests

Cherry-pick the relevant DomainConfigOverrideMigrationTest coverage from MR !379, adapted to DomainConfigMigration's shape (no separate submodule, registry-write side effect to assert).

Issue fork domain-3589035

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

  • mably committed 4ac59edf on 3.0.x
    fix: #3589035 Patch DomainConfigMigration to handle hyphenated/3-letter...
mably’s picture

Status: Active » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.