passbolt/passbolt_api · error · CustomValidationException

The armored message could not be validated.

Error message

The armored message could not be validated.

What it means

After applying all rules, parseAndValidateMessage aggregates every failed rule into $validationErrors and throws a single CustomValidationException 'The armored message could not be validated.' with the errors under a 'data' key. The full armored message and the error map are also logged via Log::error for diagnosis.

Solutions

  1. Read the data validation errors (and server error log) to see which rules failed.
  2. Re-encrypt the message for the correct, current recipient key id.
  3. Ensure exactly one recipient when the caller applies HAS_EXACTLY_ONE_RECIPIENT (encrypt per-user, one message each).
  4. Refresh the key info of the target user (verify their public key is current on the server).

Example fix

// before
const msg = await encrypt(plain, [userAKey, userBKey]); // 2 recipients
await passbolt.shareResource(id, msg);
// after
const msg = await encrypt(plain, [userAKey]); // exactly one recipient
await passbolt.shareResource(id, msg);
Defensive patterns

Strategy: try-catch

Validate before calling

const keyInfo = await getKeyInfo(recipientKey);
if (!keyInfo.key_id) throw new Error('recipient key unavailable');

Try / catch

try { parseAndValidateMessage($msg); } catch (CustomValidationException $e) { $errs = $e->getErrors()['data'] ?? []; /* re-encrypt for correct key */ }

Prevention

When it happens

Trigger: Any rule failing: message encrypted for an unexpected key id (has-key-id), multiple recipients when exactly one is required (e.g. during resource/folder share assertions), or missing recipient key ids — then the combined exception is raised at the end.

Common situations: Sharing a resource where the message was encrypted for the wrong user key, messages encrypted to multiple recipients when passbolt expects single-recipient, key rotation leaving stale key ids in messages.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/Service/OpenPGP/MessageValidationService.php:139

                        $validationErrors[$ruleName] = __('The message must contain a symmetric packet.');
                    }
                    break;
                case self::HAS_EXACTLY_ONE_RECIPIENT:
                    if (count($messageInfo['recipients']) !== 1) {
                        $validationErrors[$ruleName] = __('The message must contain only one recipient.');
                    }
                    break;
                default:
                    throw new InternalErrorException(__('Unknown key validation rule: {0}', $ruleName));
            }
        }

        // Wrap all errors together in a custom validation exception
        if (count($validationErrors)) {
            $debug = 'The armored message could not be validated' . "\n";
            $debug .= $armoredMessage . "\n" . json_encode($validationErrors);
            Log::error($debug);
            throw new CustomValidationException(__('The armored message could not be validated.'), [
                'data' => $validationErrors,
            ]);
        }

        return $messageInfo;
    }

    /**
     * Get Message Info
     *
     * @param string $armoredMessage user provided data
     * @return array see OpenPGPBackendInterface::getMessageInfo
     */
    public static function getMessageInfo(string $armoredMessage): array
    {
        return OpenPGPBackendFactory::get()->getMessageInfo($armoredMessage);
    }

View on GitHub (pinned to 31c1bbc10f)