phacility/phabricator · warning · PhutilArgumentUsageException

This host already has a registered private key ("%s"). Remov

Error message

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

What it means

Companion check to the public-key guard in `bin/almanac register`: without --force, an existing device private key file at AlmanacKeys::getKeyPath('device.key') blocks registration. Because the workflow rewrites this file (to a temp copy with restrictive permissions for ssh-keygen, then installs the final copy), silently clobbering an in-use private key would break the host's Almanac identity.

Source

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

          $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
    // on it without causing weird side effects to the file specified with
    // the `--private-key` flag. The file needs to have restrictive permissions
    // before `ssh-keygen` will willingly operate on it.
    $tmp_private = new TempFile();
    Filesystem::changePermissions($tmp_private, 0600);
    execx('chown %s %s', $phd_user, $tmp_private);
    Filesystem::writeFile($tmp_private, $raw_private_key);

    list($raw_public_key) = execx('ssh-keygen -y -f %s', $tmp_private);

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Pass --force when you deliberately want to install a new key pair.
  2. Otherwise leave the existing identity in place and remove the register step from the run.
  3. For a clean slate, delete device.pub, device.key and device.id from the Almanac keys directory shown in the message, then register again.

Example fix

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

# after (key rotation)
$ bin/almanac register --force --device web-001 --private-key ./new_device.key
Defensive patterns

Strategy: validation

Validate before calling

$priv = AlmanacKeys::getKeyPath('device.key');
$pub  = AlmanacKeys::getKeyPath('device.pub');
if (Filesystem::pathExists($priv) || Filesystem::pathExists($pub)) {
  // decide: skip, or explicit rotation with --force
  if (!$rotate) { return; }
}

Try / catch

# idempotent wrapper: 'already registered' (either key) is OK
if ! out=$(bin/almanac register "$@" 2>&1); then
  echo "$out" | grep -q 'already has a registered' && exit 0
  echo "$out" >&2; exit 1
fi

Prevention

When it happens

Trigger: Re-running register after a previous success; an earlier run that wrote device.key then failed later (e.g. at the trust check); key files present from a restored backup while --force is omitted.

Common situations: Provisioning automation that is not idempotent; recovering from a failed first registration attempt without cleaning the key directory; rotating device keys without remembering the --force flag.

Related errors


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