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
- Pass --force when you deliberately want to install a new key pair.
- Otherwise leave the existing identity in place and remove the register step from the run.
- 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
- Check both device.key and device.pub before re-running register.
- Model key rotation as its own script that always passes --force and re-trusts the new key.
- Log which identity a host currently has so re-provisioning decisions are explicit.
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
- This host already has a registered public key ("%s"). Remove
- Specify a private key with --private-key.
- The public key corresponding to the given private key is unk
- The public key corresponding to the given private key is alr
- The public key corresponding to the given private key is pro
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/bb71ca9528a616d9.
Report an issue: GitHub.