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
- Read the data validation errors (and server error log) to see which rules failed.
- Re-encrypt the message for the correct, current recipient key id.
- Ensure exactly one recipient when the caller applies HAS_EXACTLY_ONE_RECIPIENT (encrypt per-user, one message each).
- 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
- Encrypt per-recipient (one recipient per message)
- Keep recipient public keys current on server
- Check server error logs which carry the failed rule map
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
- A valid OpenPGP key must be provided.
- Could not validate message data.
- Could not validate user data.
- Invalid request, message validation rules are missing.
- The OpenPGP armored key could not be validated.
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)