passbolt/passbolt_api · error · Exception

The subscription cannot be verified. Parse error.

Error message

The subscription cannot be verified. Parse error.

What it means

The subscription key was successfully base64-decoded and its OpenPGP signature verified, but the signed payload is not valid JSON (json_decode returned null). The SubscriptionKeyAsciiForm.parse() method throws this because it cannot extract subscription metadata (customer_id, expires, etc.) from a payload it cannot decode.

Solutions

  1. Re-copy the subscription key exactly as delivered by passbolt (it is a single base64 string) and retry.
  2. Verify the key has no stray characters, line breaks inside, or truncation: `echo '<key>' | base64 -d | gpg --list-packets` should show a signature packet with a JSON literal payload.
  3. Request a new subscription key from passbolt support/account if the payload is genuinely corrupt.
  4. Check that the key matches your edition (CE vs EE) and passbolt version; very old key formats may not decode to the expected JSON.

Example fix

// before (corrupted pasted key)
$this->Subscriptions->createOrUpdate($uac, 'gAAAA...tRU NCOPIED FROM EMAIL WITH LINE BREAKS');
// after
$key = trim(preg_replace('/\s+/', '', $keyFromEmail));
$this->Subscriptions->createOrUpdate($uac, $key);
Defensive patterns

Strategy: try-catch

Validate before calling

$decoded = base64_decode($key, true);
if ($decoded === false || strpos($decoded, 'BEGIN PGP MESSAGE') === false) { /* reject before parse */ }

Try / catch

try {
    $dto = $form->parse($key);
} catch (\Exception $e) {
    Log::error('Subscription key payload not decodable: ' . $e->getMessage());
    // prompt user to re-copy the key verbatim
}

Prevention

When it happens

Trigger: Calling parse() or executing the form with a key whose signed payload was corrupted or truncated after base64 decoding — e.g. the key was manually re-typed, copy-pasted partially, or altered so the verified plaintext is no longer well-formed JSON.

Common situations: A subscription key pasted into a spreadsheet or email that mangled whitespace/characters; using a key from a different product or an outdated format; shell/heredoc escaping damage when inserting the key via CLI; a key issued for a different passbolt edition.

Understand the failure class

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/3ce097528a6a9107. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Subscription/src/Form/SubscriptionKeyAsciiForm.php:141

    /**
     * Parse the subscription.
     *
     * @param string|null $keyAscii key in ascii.
     * @return \Passbolt\Subscription\Model\Dto\SubscriptionKeyDto
     * @throws \Exception If the subscription format is not valid
     */
    public function parse(?string $keyAscii = null): SubscriptionKeyDto
    {
        if (empty($keyAscii) && !empty($this->getData('key_ascii'))) {
            $keyAscii = $this->getData('key_ascii');
        }

        $armoredSignedSubscription = $this->getArmoredSignedSubscription($keyAscii);

        $subscriptionInfoStr = $this->_verifySignature($armoredSignedSubscription);
        $subscriptionInfo = json_decode($subscriptionInfoStr, true);
        if (is_null($subscriptionInfo)) {
            throw new Exception(__('The subscription cannot be verified. Parse error.'));
        }

        $subscriptionInfo['data'] = trim($keyAscii);

        return SubscriptionKeyDto::createFromArray($subscriptionInfo);
    }

    /**
     * Get the armored subscription.
     *
     * @param string $keyAscii key in ascii
     * @return string The armored signed subscription
     * @throws \Exception If the subscription format is not valid
     */
    public function getArmoredSignedSubscription(string $keyAscii): string
    {
        $armoredSignedSubscription = base64_decode($keyAscii);
        if (!$armoredSignedSubscription) {

View on GitHub (pinned to 31c1bbc10f)