{"record":{"id":"30608b3f03b5db0b","repo":"passbolt/passbolt_api","slug":"the-message-cannot-be-verified","errorCode":null,"errorMessage":"The message cannot be verified.","messagePattern":"The message cannot be verified\\.","errorType":"exception","errorClass":"Cake\\Core\\Exception\\CakeException","httpStatus":null,"severity":"error","filePath":"src/Utility/OpenPGP/Backends/Gnupg.php","lineNumber":432,"sourceCode":"    }\n\n    /**\n     * Verify a signed message.\n     *\n     * @param string $signedText The signed message to verify.\n     * @param string|null $plainText (optional) if this parameter is passed, it will be filled with the plain text.\n     * @return array signature information\n     * @throws \\Cake\\Core\\Exception\\CakeException If the armored signed message cannot be verified.\n     */\n    public function verify(string $signedText, ?string &$plainText = null): array\n    {\n        $this->assertVerifyKey();\n        $msg = __('The message cannot be verified.');\n        try {\n            /** @psalm-suppress InvalidArgument */\n            $signature = $this->_gpg->verify($signedText, false, $plainText);\n            if (empty($signature) || $signature[0]['fingerprint'] !== $this->_verifyKeyFingerprint) {\n                throw new CakeException($msg);\n            }\n\n            return $signature;\n        } catch (Exception $e) {\n            throw new CakeException($msg . ' ' . $e->getMessage(), null, $e);\n        }\n    }\n\n    /**\n     * Sign a text.\n     *\n     * @param string $text plain text to be signed.\n     * @throws \\Cake\\Core\\Exception\\CakeException if no key was set to sign\n     * @throws \\Cake\\Core\\Exception\\CakeException if there is an issue with the key to sign\n     * @return string signed text\n     */\n    public function sign(string $text): string\n    {","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Utility/OpenPGP/Backends/Gnupg.php#L414-L450","documentation":"Thrown when verify($signedText, $plainText) finds no signature or one whose fingerprint does not match the configured verify key ($this->_verifyKeyFingerprint set via setVerifyKey). It asserts the signed message was produced by the expected key.","triggerScenarios":"verify($signedText) where $this->_gpg->verify() returns empty, or $signature[0]['fingerprint'] !== $this->_verifyKeyFingerprint — message signed by another key, unsigned payload, or malformed signed text.","commonSituations":"Verifying a user-signed message against the server verify key; server key rotated so old signatures no longer match; passing an encrypted (not signed) message to verify.","solutions":["Check the message actually contains a PGP SIGNATURE / SIGNED MESSAGE block","Set the verify key to the fingerprint of the key that actually signed: setVerifyKey($signerFingerprint)","If the server key rotated, keep the old public key in the keyring and use its fingerprint for legacy verification","Inspect $signature[0]['fingerprint'] in a debug run to see who really signed"],"exampleFix":"// before\n$gpg->setVerifyKey($serverFingerprint);\n$sig = $gpg->verify($userSignedMessage); // fingerprint mismatch -> CakeException\n// after\n$gpg->setVerifyKey($userFingerprint);\n$sig = $gpg->verify($userSignedMessage);","handlingStrategy":"try-catch","validationCode":"if (!str_contains($signedText, '-----BEGIN PGP SIGNATURE-----') && !str_contains($signedText, '-----BEGIN PGP SIGNED MESSAGE-----')) {\n    throw new InvalidArgumentException('Input is not a signed message');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $signature = $gpg->verify($signedText, $plainText);\n} catch (CakeException $e) {\n    $this->log('Verify failed: ' . $e->getMessage());\n    throw new VerificationException('Message signature could not be validated.', 0, $e);\n}","preventionTips":["Set the verify key to the actual signer's fingerprint before calling verify","Ensure signer public keys are imported in the keyring","Sanitize transport encoding so armored text is not corrupted","Keep previous server public keys when rotating for legacy verification"],"tags":["openpgp","signature","verification","gnupg"],"backgroundTag":"openpgp-signature-verification-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"}