phacility/phabricator · critical · Exception

Database "%s" is configured as a replica, but there is no ma

Error message

Database "%s" is configured as a replica, but there is no master configured.

What it means

A replica is configured, but no entry in `cluster.database` has `role => 'master'`, so `$master_keys` is empty and there is nothing for the replica to follow. The parser only falls back to implicit selection when at least one master exists; with zero masters it throws immediately.

Source

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

            'configuration. Replicas use the same configuration as the '.
            'master they follow.',
            $ref->getRefKey()));
      }

      $master_key = idx($server, 'master');
      if ($master_key === null) {
        if ($is_partitioned) {
          throw new Exception(
            pht(
              'Database "%s" is configured as a replica, but does not '.
              'specify which "master" it follows in configuration. Valid '.
              'masters are: %s.',
              $ref->getRefKey(),
              implode(', ', $master_keys)));
        } else if ($master_keys) {
          $master_key = head($master_keys);
        } else {
          throw new Exception(
            pht(
              'Database "%s" is configured as a replica, but there is no '.
              'master configured.',
              $ref->getRefKey()));
        }
      }

      if (!isset($ref_map[$master_key])) {
        throw new Exception(
          pht(
            'Database "%s" is configured as a replica and specifies a '.
            'master ("%s"), but that master is not a valid master. Valid '.
            'masters are: %s.',
            $ref->getRefKey(),
            $master_key,
            implode(', ', $master_keys)));
      }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Set the intended master entry's role to exactly `role => 'master'` (lowercase).
  2. If there is genuinely no local master (this install only mirrors a remote one), remove the cluster.database replica config entirely — a stand-alone install uses the standard mysql.* settings.
  3. Verify with `bin/config get cluster.database` that at least one entry reads `role => 'master'`.

Example fix

// before
'db-primary' => array(
  'host' => 'db1.example.com',
  'role' => 'primary',
),
// after
'db-primary' => array(
  'host' => 'db1.example.com',
  'role' => 'master',
),
Defensive patterns

Strategy: validation

Validate before calling

function assertAtLeastOneMaster(array $config) {
  $masters = array();
  foreach ($config as $key => $server) {
    if (idx($server, 'role') === 'master') { $masters[] = $key; }
  }
  if (!$masters) {
    throw new Exception(
      'cluster.database needs at least one entry with role => "master".');
  }
  return $masters;
}

Type guard

function isMasterEntry(array $server) {
  return isset($server['role']) && $server['role'] === 'master';
}

Prevention

When it happens

Trigger: Every entry in `cluster.database` has a role that is not exactly the lowercase string `'master'` — e.g. `'Master'`, `'primary'`, or `'slave'` — while at least one entry is a replica. Note the `disabled` flag does not remove a master from this list, so the cause is almost always the role value itself.

Common situations: Hand-editing config and typoing the role; renaming terminology to primary/replica in config files; accidentally deleting or commenting out the master entry during cleanup.

Related errors


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