{"record":{"id":"b5cd3bf4c959536b","repo":"phacility/phabricator","slug":"this-host-already-has-a-registered-public-key-s","errorCode":null,"errorMessage":"This host already has a registered public key (\"%s\"). Remove this key before registering the host, or use --force to overwrite it.","messagePattern":"This host already has a registered public key \\(\"(.+?)\"\\)\\. Remove this key before registering the host, or use --force to overwrite it\\.","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/applications/almanac/management/AlmanacManagementRegisterWorkflow.php","lineNumber":110,"sourceCode":"\n    $tmp = new TempFile();\n    list($err) = exec_manual('chown %s %s', $phd_user, $tmp);\n    if ($err) {\n      throw new PhutilArgumentUsageException(\n        pht(\n          'Unable to change ownership of an identity file to daemon user '.\n          '\"%s\". Run this command as %s or root.',\n          $phd_user,\n          $phd_user));\n    }\n\n    $stored_public_path = AlmanacKeys::getKeyPath('device.pub');\n    $stored_private_path = AlmanacKeys::getKeyPath('device.key');\n    $stored_device_path = AlmanacKeys::getKeyPath('device.id');\n\n    if (!$args->getArg('force')) {\n      if (Filesystem::pathExists($stored_public_path)) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'This host already has a registered public key (\"%s\"). '.\n            'Remove this key before registering the host, or use '.\n            '--force to overwrite it.',\n            Filesystem::readablePath($stored_public_path)));\n      }\n\n      if (Filesystem::pathExists($stored_private_path)) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'This host already has a registered private key (\"%s\"). '.\n            'Remove this key before registering the host, or use '.\n            '--force to overwrite it.',\n            Filesystem::readablePath($stored_private_path)));\n      }\n    }\n\n    // NOTE: We're writing the private key here so we can change permissions","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/almanac/management/AlmanacManagementRegisterWorkflow.php#L92-L128","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["If you intend to replace the identity, add --force: bin/almanac register --force --device ... --private-key ....","If the existing registration is correct, no action is needed; skip the register step in your provisioning.","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."],"exampleFix":"# before\n$ bin/almanac register --device web-001 --private-key ./device.key\nUsage Exception: This host already has a registered public key (\"../almanac/keys/device.pub\"). ...\n\n# after (intentional re-registration)\n$ bin/almanac register --force --device web-001 --private-key ./device.key","handlingStrategy":"validation","validationCode":"// Only register when no public key is installed yet (idempotent provisioning)\n$pub = AlmanacKeys::getKeyPath('device.pub');\nif (Filesystem::pathExists($pub) && !$force) {\n  // already registered on this host; skip\n  return;\n}","typeGuard":null,"tryCatchPattern":"# shell: treat 'already has a registered' as success in idempotent scripts\nout=$(bin/almanac register --device \"$D\" --private-key \"$K\" 2>&1) || {\n  echo \"$out\" | grep -q 'already has a registered' && exit 0\n  echo \"$out\" >&2; exit 1;\n}","preventionTips":["Make register steps conditional on key-file existence rather than unconditional.","Pass --force only in an explicit key-rotation path.","Exclude the Almanac key directory from golden images and backups unless intentionally migrating identity."],"tags":["phabricator","almanac","cli","register","idempotency","ssh-key"],"backgroundTag":"resource-already-exists","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}