passbolt/passbolt_api · error · Cake\Core\Exception\CakeException
Can not sign without a key. Set a sign key first.
Error message
Can not sign without a key. Set a sign key first.
What it means
assertSignKey() is a precondition check for OpenPGP signing operations in OpenPGPCommonAssertsTrait. It throws a CakeException when the private property _signKeyFingerprint is empty, because GnuPG cannot create a signature without a sign key having been set via setSignKey().
Solutions
- Call setSignKey() with a valid secret-key fingerprint before signing.
- Ensure the sign key fingerprint is configured in application settings and loaded into the OpenPGP utility during bootstrap.
- Confirm the fingerprint actually set is non-empty (log/inspect the value passed to setSignKey).
Example fix
// before $signed = $gpg->sign($text); // throws: no sign key // after $gpg->setSignKey($signKeyFingerprint, $passphrase); $signed = $gpg->sign($text);
Defensive patterns
Strategy: type-guard
Validate before calling
if (empty($gpg->getSignKeyFingerprint())) {
$gpg->setSignKey($configSignKeyFingerprint, $passphrase);
} Type guard
function canSign($gpg): bool {
return isset($gpg) && !empty($gpg->getSignKeyFingerprint());
} Try / catch
try {
$signed = $gpg->sign($text);
} catch (\Cake\Core\Exception\CakeException $e) {
if (str_contains($e->getMessage(), 'sign without a key')) {
$gpg->setSignKey($fingerprint, $passphrase);
$signed = $gpg->sign($text);
} else { throw $e; }
} Prevention
- Centralize OpenPGP key setup in a single factory/bootstrap so sign key is always set.
- Never construct signing-capable instances ad hoc in commands or tests without the shared factory.
- Assert key setup in unit tests before exercising sign paths.
When it happens
Trigger: Calling sign() (or any operation that internally calls assertSignKey) on an OpenPGP utility instance where setSignKey() was never called, or was called with an empty/invalid fingerprint so _signKeyFingerprint stayed empty.
Common situations: Forgotten setSignKey() call before signing emails or payloads; signing code executed in a context (CLI task, test) where the key setup bootstrap didn't run; refactors that moved signing into a new service without carrying the key configuration over.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- A value for the theme should be provided.
- Can not decrypt without a key. Set a secret key first.
- Can not encrypt without a key. Set a public key first.
- Can not verify without a key. Set a verification key first.
- Could not sign the text.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/05abf120411dcdfd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Utility/OpenPGP/Traits/OpenPGPCommonAssertsTrait.php:68
* @return void
*/
public function assertKeyInKeyring(string $fingerprint): void
{
if (!$this->isKeyInKeyring($fingerprint)) {
throw new CakeException(__('The key {0} was not found in the keyring', $fingerprint));
}
}
/**
* Assert the signature key is set
*
* @throws \Cake\Core\Exception\CakeException if not signature key is set
* @return void
*/
public function assertSignKey(): void
{
if (empty($this->_signKeyFingerprint)) {
throw new CakeException('Can not sign without a key. Set a sign key first.');
}
}
/**
* Assert the verification key is set
*
* @throws \Cake\Core\Exception\CakeException if not signature key is set
* @return void
*/
public function assertVerifyKey(): void
{
if (empty($this->_verifyKeyFingerprint)) {
throw new CakeException('Can not verify without a key. Set a verification key first.');
}
}
/**
* Check if an encryption key is setView on GitHub (pinned to 31c1bbc10f)