passbolt/passbolt_api · error · SubscriptionSignatureException
The subscription key cannot be verified.
Error message
The subscription key cannot be verified.
What it means
_verifySignature() throws SubscriptionSignatureException when the OpenPGP verification of the subscription payload fails: the GnuPG/OpenPGP backend (import of the vendor public key succeeded, key fingerprint set) could not verify the signature over the armored message. The underlying GPG backend message is appended to the exception text.
Solutions
- Read the appended GPG message in the exception/log to see the concrete verification failure.
- Do not alter the key: submit the exact base64 string from passbolt — any edit invalidates the signature.
- Fix keyring health for the web user: `sudo chown -R www-data:www-data /var/lib/passbolt/.gnupg` and ensure the gnupg PHP extension works.
- Confirm the key matches your edition/version and request a re-issued key from passbolt if verification still fails.
Example fix
// before: edited key payload
$key = str_replace('"expires":"2020', '"expires":"2099', $key);
createOrUpdate($uac, $key); // signature check fails
// after
createOrUpdate($uac, $originalUnmodifiedKey); Defensive patterns
Strategy: try-catch
Validate before calling
// before submitting, verify locally: // base64 -d key.b64 | gpg --verify - 2>&1
Try / catch
try {
$dto = $form->parse($key);
} catch (SubscriptionSignatureException $e) {
Log::error($e->getMessage()); // includes underlying GPG verify error
// do not retry with a modified key; request a fresh key
} Prevention
- Submit the key exactly as issued — any edit breaks the signature
- Keep the gnupg extension and web-user keyring healthy (ownership of ~/.gnupg)
- Match key edition/version to the installed passbolt release
When it happens
Trigger: parse() calls _verifySignature() and $this->getGpg()->verify($subscriptionSigned, $subscription) throws — tampered payload, signature made by a key not matching the imported vendor public key, corrupted armored message, or the gpg keyring/OpenPGP backend malfunctioning (e.g. gnupg extension issue, stale keyring).
Common situations: Manually editing the subscription JSON then re-submitting; a key issued for a different passbolt product; mixed or corrupted Gnupg keyring under the web-server user (e.g. ~/.gnupg ownership problems); PHP gnupg/OpenPGP-PGP backend mismatch after server migration.
Related errors
- The subscription cannot be verified. Parse error.
- The subscription format is not valid. Invalid format.
- Only administrators can delete the subscription.
- Subscription key could not be found.
- The OpenPGP user key cannot be found.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/1a6cf3d882911bda.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Subscription/src/Form/SubscriptionKeyAsciiForm.php:197
*/
protected function _verifySignature(string $subscriptionSigned): string
{
$msg = __('The subscription key cannot be verified.');
$subscription = '';
$filePublicKey = Configure::read('passbolt.plugins.edition.subscriptionKey.public');
if (!$filePublicKey || !file_exists($filePublicKey)) {
$msg .= ' ' . __('The passbolt OpenPGP public key could not be found.');
throw new SubscriptionSignatureException($subscriptionSigned, $msg);
}
$subscriptionPublicKey = file_get_contents($filePublicKey);
$fingerprint = $this->getGpg()->importKeyIntoKeyring($subscriptionPublicKey);
$this->getGpg()->setVerifyKeyFromFingerprint($fingerprint);
try {
$this->getGpg()->verify($subscriptionSigned, $subscription);
} catch (Exception $e) {
$msg .= ' ' . $e->getMessage();
throw new SubscriptionSignatureException($subscriptionSigned, $msg);
}
/** @psalm-suppress NullableReturnStatement this is always a string */
return $subscription;
}
/**
* @return \App\Utility\OpenPGP\OpenPGPBackend
*/
private function getGpg(): OpenPGPBackend
{
if (is_null($this->_gpg)) {
$this->_gpg = OpenPGPBackendFactory::get();
}
return $this->_gpg;
}
View on GitHub (pinned to 31c1bbc10f)