{"record":{"id":"2dd4b4bbf76df2d4","repo":"phacility/phabricator","slug":"this-public-key-is-already-associated-with-another","errorCode":null,"errorMessage":"This public key is already associated with another user or device. Each key must unambiguously identify a single unique owner.","messagePattern":"This public key is already associated with another user or device\\. Each key must unambiguously identify a single unique owner\\.","errorType":"validation","errorClass":"PhabricatorApplicationTransactionValidationException","httpStatus":null,"severity":"error","filePath":"src/applications/auth/editor/PhabricatorAuthSSHKeyEditor.php","lineNumber":212,"sourceCode":"\n    return $errors;\n  }\n\n  protected function didCatchDuplicateKeyException(\n    PhabricatorLiskDAO $object,\n    array $xactions,\n    Exception $ex) {\n\n    $errors = array();\n    $errors[] = new PhabricatorApplicationTransactionValidationError(\n      PhabricatorAuthSSHKeyTransaction::TYPE_KEY,\n      pht('Duplicate'),\n      pht(\n        'This public key is already associated with another user or device. '.\n        'Each key must unambiguously identify a single unique owner.'),\n      null);\n\n    throw new PhabricatorApplicationTransactionValidationException($errors);\n  }\n\n\n  protected function shouldSendMail(\n    PhabricatorLiskDAO $object,\n    array $xactions) {\n    return true;\n  }\n\n  protected function getMailSubjectPrefix() {\n    return pht('[SSH Key]');\n  }\n\n  protected function getMailThreadID(PhabricatorLiskDAO $object) {\n    return 'ssh-key-'.$object->getPHID();\n  }\n\n  protected function applyFinalEffects(","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/auth/editor/PhabricatorAuthSSHKeyEditor.php#L194-L230","documentation":"PhabricatorAuthSSHKeyEditor catches the database duplicate-key exception for SSH public keys (the key is stored with a unique hash) and rethrows it as a transaction validation error on the key transaction type. The message enforces the invariant that one public key maps to exactly one user or device, so the same key material cannot be registered twice.","triggerScenarios":"Adding an SSH key (user key or device key) that is byte-identical (same unique key hash) to one already registered on this install - e.g., re-adding a key from a cloned VM image, pasting the same id_rsa.pub under a second account, or a keypair reused across a laptop and a CI node that tries to register it separately.","commonSituations":"Shared/cloned machines re-registering the default key; users pasting the same key twice after switching accounts; admins importing keys that overlap with existing rows; authorized_keys automation that creates rather than updates.","solutions":["Query PhabricatorAuthSSHKeyQuery->withKeys(array($public_key)) first; if a row exists, update or delete it instead of inserting a new one.","If the key legitimately belongs to a different user/device, remove it from its current owner first.","On cloned machines, generate a fresh keypair rather than reusing the baked-in one.","Catch PhabricatorApplicationTransactionValidationException in API flows and surface the field error to the caller."],"exampleFix":"// before: upload a key that is already registered\n$key = PhabricatorAuthSSHKey::initializeNewSSHKey($user)\n  ->setName('laptop')\n  ->setKey($public_key);\n\n// after: check for an existing identical key first\n$existing = id(new PhabricatorAuthSSHKeyQuery())\n  ->setViewer($viewer)\n  ->withKeys(array($public_key))\n->executeOne();\nif ($existing) {\n  // update/delete $existing instead of inserting a duplicate\n}","handlingStrategy":"validation","validationCode":"// Pre-check for an identical key before upload\n$existing = id(new PhabricatorAuthSSHKeyQuery())\n  ->setViewer($viewer)\n  ->withKeys(array($public_key))\n  ->executeOne();\nif ($existing) {\n  // update or delete $existing instead of inserting a duplicate\n}","typeGuard":null,"tryCatchPattern":"try {\n  $editor->applyTransactions($ssh_key, $xactions);\n} catch (PhabricatorApplicationTransactionValidationException $ex) {\n  return $this->newDialog()->setValidationException($ex);\n}","preventionTips":["Generate a fresh keypair per machine; never reuse keys from cloned images.","Before registering a key, search with PhabricatorAuthSSHKeyQuery->withKeys().","Automate key rotation as update-or-insert, not blind insert."],"tags":["phabricator","ssh","public-key","duplicate-key","validation","php"],"backgroundTag":"duplicate-unique-constraint","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}