Eugeny/tabby · warning · Error
Passphrase prompt cancelled
Error message
Passphrase prompt cancelled
What it means
Thrown inside loadPrivateKeyWithPassphraseMaybe() when an encrypted private key needs a passphrase and the user dismisses the PromptModalComponent passphrase dialog (Esc / backdrop / cancel). The modal.result promise rejects on dismissal; the catch rethrows this error to abort key loading.
Source
Thrown at tabby-ssh/src/session/ssh.ts:967
passphrase = await this.passwordStorage.loadPrivateKeyPassword(keyHash)
triedSavedPassphrase = true
continue
}
if ([
'Error: Keys(KeyIsEncrypted)',
'Error: Keys(SshKey(Ppk(Encrypted)))',
'Error: Keys(SshKey(Ppk(IncorrectMac)))',
'Error: Keys(SshKey(Crypto))',
].includes(e.toString())) {
await this.passwordStorage.deletePrivateKeyPassword(keyHash)
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = 'Private key passphrase'
modal.componentInstance.password = true
modal.componentInstance.showRememberCheckbox = true
const result = await modal.result.catch(() => {
throw new Error('Passphrase prompt cancelled')
})
passphrase = result?.value
if (passphrase && result.remember) {
this.passwordStorage.savePrivateKeyPassword(keyHash, passphrase)
}
} else {
this.notifications.error('Could not read the private key', e.toString())
throw e
}
}
}
}
ref (): void {
this.refCount++
}
View on GitHub (pinned to 14e2d60b9b)
Solutions
- Re-open the key and enter the correct passphrase instead of cancelling.
- If running headless, pre-store the passphrase via passwordStorage.savePrivateKeyPassword(keyHash, passphrase) so no modal is needed.
- Use an unencrypted key, or decrypt it once with ssh-keygen -p -f <key> so no passphrase is required.
- Use an SSH agent (ssh-add) so the key passphrase is handled outside Tabby's modal path.
- Ensure the modal is not auto-dismissed by router/background changes during the prompt.
Example fix
// before: encrypted key, user cancels modal -> 'Passphrase prompt cancelled' // after: decrypt the key once // ssh-keygen -p -f ~/.ssh/id_ed25519 // or pre-seed the remembered passphrase in passwordStorage before connecting
Defensive patterns
Strategy: try-catch
Try / catch
try {
await session.loadPrivateKeyWithPassphraseMaybe(key)
} catch (e) {
if (e.message === 'Passphrase prompt cancelled') {
// user opted out; abort key auth gracefully
return
}
throw e
} Prevention
- Pre-store the passphrase with passwordStorage.savePrivateKeyPassword so no modal is needed.
- Decrypt the key once with ssh-keygen -p to remove the passphrase.
- Load keys into ssh-agent to bypass Tabby's passphrase modal entirely.
- Avoid running interactive SSH flows headless where the modal cannot be answered.
When it happens
Trigger: russh.KeyPair.parse fails with one of 'KeyIsEncrypted', 'Ppk(Encrypted)', 'Ppk(IncorrectMac)', or 'SshKey(Crypto)', the stored passphrase (if any) was already tried and deleted, the passphrase modal is opened, and the user cancels it. modal.result.catch at ssh.ts:966 then throws 'Passphrase prompt cancelled'.
Common situations: User hits Escape on the passphrase prompt; clicks outside the modal (backdrop dismiss); switches away and the modal auto-dismisses; automated/headless run where no one is present to answer the modal; a previously-remembered passphrase became wrong (key re-encrypted) and the user cancels the re-prompt.
Related errors
- Vault unlock cancelled
- Download cancelled
- ${profile.options.host}: jump host "${profile.options.jumpHo
- No private keys in profile
- WinSCP not found
AI-assisted analysis of Eugeny/tabby@14e2d60b9b (2026-08-12).
Data as JSON: /api/errors/c282f12ac2a492da.
Report an issue: GitHub.