phacility/phabricator · critical · Exception

This server is configured with multiple master databases, bu

Error message

This server is configured with multiple master databases, but master "%s" is missing a "partition" configuration key to define application partitioning.

What it means

When cluster.databases defines more than one master, Phabricator partitions applications across them. Each master must carry a 'partition' key listing the application databases (or 'default') it owns; a master missing that array key fails config parsing with this exception.

Source

Thrown at src/infrastructure/cluster/PhabricatorDatabaseRefParser.php:91

        $master_count++;
      }

      $refs[$key] = $ref;
    }

    $is_partitioned = ($master_count > 1);
    if ($is_partitioned) {
      $default_ref = null;
      $partition_map = array();
      foreach ($refs as $key => $ref) {
        if (!$ref->getIsMaster()) {
          continue;
        }

        $server = $config[$key];
        $partition = idx($server, 'partition');
        if (!is_array($partition)) {
          throw new Exception(
            pht(
              'This server is configured with multiple master databases, '.
              'but master "%s" is missing a "partition" configuration key to '.
              'define application partitioning.',
              $ref->getRefKey()));
        }

        $application_map = array();
        foreach ($partition as $application) {
          if ($application === 'default') {
            if ($default_ref) {
              throw new Exception(
                pht(
                  'Multiple masters (databases "%s" and "%s") specify that '.
                  'they are the "default" partition. Only one master may be '.
                  'the default.',
                  $ref->getRefKey(),
                  $default_ref->getRefKey()));

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Add a 'partition' array to every master in cluster.databases, e.g. array('partition' => array('default')) or array('partition' => array('maniphest', 'differential')).
  2. Ensure exactly one master claims 'default' and applications are allocated to only one master each.
  3. Re-check with 'bin/config get cluster.databases' after editing, then reload the page.
  4. If you do not actually need multiple masters, go back to a single master entry (partitioning is then not required).

Example fix

// before
[
  ["master" => true, "host" => "db1", "port" => 3306],
  ["master" => true, "host" => "db2", "port" => 3306]
]

// after
[
  ["master" => true, "host" => "db1", "port" => 3306,
   "partition" => ["default"]],
  ["master" => true, "host" => "db2", "port" => 3306,
   "partition" => ["maniphest", "differential"]]
]
Defensive patterns

Strategy: validation

Validate before calling

// Lint cluster.databases before it reaches production
try {
  $refs = id(new PhabricatorDatabaseRefParser())
    ->newRefs($cluster_database_config);
} catch (Exception $ex) {
  // block the deploy: $ex->getMessage() names the offending master
}

Prevention

When it happens

Trigger: Adding a second master entry to cluster.databases without adding a 'partition' list to the existing one, so $master_count > 1 while some master's config has no 'partition' array. Parsing happens when the database ref list is built (early in any request).

Common situations: Scaling out from a single database by pasting a second master block while forgetting the original also needs a partition map; following outdated cluster documentation that predates partitioning; YAML/JSON indentation making 'partition' a sibling of the wrong node.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/4e23671f1ac2af7b. Report an issue: GitHub.