{"record":{"id":"6ebfc42466efe245","repo":"passbolt/passbolt_api","slug":"the-armored-message-could-not-be-validated","errorCode":null,"errorMessage":"The armored message could not be validated.","messagePattern":"The armored message could not be validated\\.","errorType":"validation","errorClass":"CustomValidationException","httpStatus":422,"severity":"error","filePath":"src/Service/OpenPGP/MessageValidationService.php","lineNumber":139,"sourceCode":"                        $validationErrors[$ruleName] = __('The message must contain a symmetric packet.');\n                    }\n                    break;\n                case self::HAS_EXACTLY_ONE_RECIPIENT:\n                    if (count($messageInfo['recipients']) !== 1) {\n                        $validationErrors[$ruleName] = __('The message must contain only one recipient.');\n                    }\n                    break;\n                default:\n                    throw new InternalErrorException(__('Unknown key validation rule: {0}', $ruleName));\n            }\n        }\n\n        // Wrap all errors together in a custom validation exception\n        if (count($validationErrors)) {\n            $debug = 'The armored message could not be validated' . \"\\n\";\n            $debug .= $armoredMessage . \"\\n\" . json_encode($validationErrors);\n            Log::error($debug);\n            throw new CustomValidationException(__('The armored message could not be validated.'), [\n                'data' => $validationErrors,\n            ]);\n        }\n\n        return $messageInfo;\n    }\n\n    /**\n     * Get Message Info\n     *\n     * @param string $armoredMessage user provided data\n     * @return array see OpenPGPBackendInterface::getMessageInfo\n     */\n    public static function getMessageInfo(string $armoredMessage): array\n    {\n        return OpenPGPBackendFactory::get()->getMessageInfo($armoredMessage);\n    }\n","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Service/OpenPGP/MessageValidationService.php#L121-L157","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nconst msg = await encrypt(plain, [userAKey, userBKey]); // 2 recipients\nawait passbolt.shareResource(id, msg);\n// after\nconst msg = await encrypt(plain, [userAKey]); // exactly one recipient\nawait passbolt.shareResource(id, msg);","handlingStrategy":"try-catch","validationCode":"const keyInfo = await getKeyInfo(recipientKey);\nif (!keyInfo.key_id) throw new Error('recipient key unavailable');","typeGuard":null,"tryCatchPattern":"try { parseAndValidateMessage($msg); } catch (CustomValidationException $e) { $errs = $e->getErrors()['data'] ?? []; /* re-encrypt for correct key */ }","preventionTips":["Encrypt per-recipient (one recipient per message)","Keep recipient public keys current on server","Check server error logs which carry the failed rule map"],"tags":["openpgp","gpg","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}