phacility/phabricator · warning · PhutilArgumentUsageException

This host already has a registered public key ("%s"). Remove

Error message

This host already has a registered public key ("%s"). Remove this key before registering the host, or use --force to overwrite it.

What it means

Usage exception from `bin/almanac register`: without --force, the workflow refuses to overwrite the already-existing device public key file at AlmanacKeys::getKeyPath('device.pub') (path shown via Filesystem::readablePath). Re-registering blindly could strand the host's current identity or desynchronize keys, so an explicit choice is required.

Source

Thrown at src/applications/almanac/management/AlmanacManagementRegisterWorkflow.php:110

    $tmp = new TempFile();
    list($err) = exec_manual('chown %s %s', $phd_user, $tmp);
    if ($err) {
      throw new PhutilArgumentUsageException(
        pht(
          'Unable to change ownership of an identity file to daemon user '.
          '"%s". Run this command as %s or root.',
          $phd_user,
          $phd_user));
    }

    $stored_public_path = AlmanacKeys::getKeyPath('device.pub');
    $stored_private_path = AlmanacKeys::getKeyPath('device.key');
    $stored_device_path = AlmanacKeys::getKeyPath('device.id');

    if (!$args->getArg('force')) {
      if (Filesystem::pathExists($stored_public_path)) {
        throw new PhutilArgumentUsageException(
          pht(
            'This host already has a registered public key ("%s"). '.
            'Remove this key before registering the host, or use '.
            '--force to overwrite it.',
            Filesystem::readablePath($stored_public_path)));
      }

      if (Filesystem::pathExists($stored_private_path)) {
        throw new PhutilArgumentUsageException(
          pht(
            'This host already has a registered private key ("%s"). '.
            'Remove this key before registering the host, or use '.
            '--force to overwrite it.',
            Filesystem::readablePath($stored_private_path)));
      }
    }

    // NOTE: We're writing the private key here so we can change permissions

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. If you intend to replace the identity, add --force: bin/almanac register --force --device ... --private-key ....
  2. If the existing registration is correct, no action is needed; skip the register step in your provisioning.
  3. To fully reset, remove the files the message points at (device.pub, device.key, device.id under the Almanac keys directory) and rerun without --force.

Example fix

# before
$ bin/almanac register --device web-001 --private-key ./device.key
Usage Exception: This host already has a registered public key ("../almanac/keys/device.pub"). ...

# after (intentional re-registration)
$ bin/almanac register --force --device web-001 --private-key ./device.key
Defensive patterns

Strategy: validation

Validate before calling

// Only register when no public key is installed yet (idempotent provisioning)
$pub = AlmanacKeys::getKeyPath('device.pub');
if (Filesystem::pathExists($pub) && !$force) {
  // already registered on this host; skip
  return;
}

Try / catch

# shell: treat 'already has a registered' as success in idempotent scripts
out=$(bin/almanac register --device "$D" --private-key "$K" 2>&1) || {
  echo "$out" | grep -q 'already has a registered' && exit 0
  echo "$out" >&2; exit 1;
}

Prevention

When it happens

Trigger: Running register twice on the same host (e.g. re-running provisioning); a partially failed earlier registration that already wrote device.pub; restoring a host from a snapshot that already contains the key files.

Common situations: Idempotent configuration-management (Puppet/Ansible) re-runs; testing the register flow repeatedly on a scratch host; hosts re-imaged from templates that include the key directory.

Related errors


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