phacility/phabricator · error · PhutilArgumentUsageException

Two servers (at indexes "%s" and "%s") both bind to the same

Error message

Two servers (at indexes "%s" and "%s") both bind to the same port ("%s"). Each server must bind to a unique port.

What it means

Thrown while validating the 'servers' list in the Aphlict config when two server entries declare the same 'port' value. The workflow builds a $port_map keyed by port and rejects duplicates regardless of server type, because the Node.js notification server cannot bind two listeners to one port.

Source

Thrown at src/applications/aphlict/management/PhabricatorAphlictManagementWorkflow.php:111

    $has_admin = false;
    $port_map = array();
    foreach ($servers as $index => $server) {
      PhutilTypeSpec::checkMap(
        $server,
        array(
          'type' => 'string',
          'port' => 'int',
          'listen' => 'optional string|null',
          'ssl.key' => 'optional string|null',
          'ssl.cert' => 'optional string|null',
          'ssl.chain' => 'optional string|null',
        ));

      $port = $server['port'];
      if (!isset($port_map[$port])) {
        $port_map[$port] = $index;
      } else {
        throw new PhutilArgumentUsageException(
          pht(
            'Two servers (at indexes "%s" and "%s") both bind to the same '.
            'port ("%s"). Each server must bind to a unique port.',
            $port_map[$port],
            $index,
            $port));
      }

      $type = $server['type'];
      switch ($type) {
        case 'admin':
          $has_admin = true;
          break;
        case 'client':
          $has_client = true;
          break;
        default:
          throw new PhutilArgumentUsageException(

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Open the config and give each server entry in "servers" a distinct "port" (convention: client 22280, admin 22281)
  2. Check no other service already uses the new port: ss -ltnp | grep <port>
  3. If you actually want one port for both roles, note Aphlict does not support that — keep separate admin and client listeners

Example fix

// before
"servers": [
  {"type": "client", "port": 22280, "listen": "0.0.0.0"},
  {"type": "admin",  "port": 22280}
]
// after
"servers": [
  {"type": "client", "port": 22280, "listen": "0.0.0.0"},
  {"type": "admin",  "port": 22281, "listen": "127.0.0.1"}
]
Defensive patterns

Strategy: validation

Validate before calling

$ports = array();
foreach ($config['servers'] as $i => $server) {
  $port = $server['port'];
  if (isset($ports[$port])) {
    throw new InvalidArgumentException("Duplicate port {$port} at indexes {$ports[$port]} and {$i}");
  }
  $ports[$port] = $i;
}

Prevention

When it happens

Trigger: Two entries in the "servers" array share a "port" value — e.g. an admin server on 22281 and a client server also set to 22281 (copy-paste from the example config where only one port was changed).

Common situations: Cloning the stock example config (client 22280 / admin 22281) and editing only one field; merging two team configs that each chose the same port; changing a port to dodge a conflict but forgetting a second entry.

Related errors


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