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

  1. Call setSignKey() with a valid secret-key fingerprint before signing.
  2. Ensure the sign key fingerprint is configured in application settings and loaded into the OpenPGP utility during bootstrap.
  3. 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

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


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 set

View on GitHub (pinned to 31c1bbc10f)