phacility/phabricator · error · PhabricatorApplicationTransactionValidationException
This public key is already associated with another user or d
Error message
This public key is already associated with another user or device. Each key must unambiguously identify a single unique owner.
What it means
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.
Source
Thrown at src/applications/auth/editor/PhabricatorAuthSSHKeyEditor.php:212
return $errors;
}
protected function didCatchDuplicateKeyException(
PhabricatorLiskDAO $object,
array $xactions,
Exception $ex) {
$errors = array();
$errors[] = new PhabricatorApplicationTransactionValidationError(
PhabricatorAuthSSHKeyTransaction::TYPE_KEY,
pht('Duplicate'),
pht(
'This public key is already associated with another user or device. '.
'Each key must unambiguously identify a single unique owner.'),
null);
throw new PhabricatorApplicationTransactionValidationException($errors);
}
protected function shouldSendMail(
PhabricatorLiskDAO $object,
array $xactions) {
return true;
}
protected function getMailSubjectPrefix() {
return pht('[SSH Key]');
}
protected function getMailThreadID(PhabricatorLiskDAO $object) {
return 'ssh-key-'.$object->getPHID();
}
protected function applyFinalEffects(View on GitHub (pinned to 5720a38cfe)
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.
Example fix
// before: upload a key that is already registered
$key = PhabricatorAuthSSHKey::initializeNewSSHKey($user)
->setName('laptop')
->setKey($public_key);
// after: check for an existing identical key first
$existing = id(new PhabricatorAuthSSHKeyQuery())
->setViewer($viewer)
->withKeys(array($public_key))
->executeOne();
if ($existing) {
// update/delete $existing instead of inserting a duplicate
} Defensive patterns
Strategy: validation
Validate before calling
// Pre-check for an identical key before upload
$existing = id(new PhabricatorAuthSSHKeyQuery())
->setViewer($viewer)
->withKeys(array($public_key))
->executeOne();
if ($existing) {
// update or delete $existing instead of inserting a duplicate
} Try / catch
try {
$editor->applyTransactions($ssh_key, $xactions);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
return $this->newDialog()->setValidationException($ex);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- This contact number is already in use.
- No public key was provided.
- Service "%s" is unrecognized, restricted, or you do not have
- When creating a new Almanac interface via the Conduit API, y
- Device "%s" is unrecognized, restricted, or you do not have
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/2dd4b4bbf76df2d4.
Report an issue: GitHub.