gchq/CyberChef · error · OperationError

Couldn't verify message: ${err}

Error message

Couldn't verify message: ${err}

What it means

Outer catch around the entire unbox + verify block in PGPDecryptAndVerify (lines 79-119). It catches kbpgp.unbox failures AND the inner OperationErrors 'Could not identify a key manager' (529) and 'The data does not appear to be signed' (530), re-throwing all as 'Couldn't verify message: ${err}'. This is the message users actually see; the inner causes appear only inside the interpolated suffix.

Source

Thrown at src/core/operations/PGPDecryptAndVerify.mjs:118

                        }
                        text += "\n";
                    }
                    text += [
                        `PGP key ID: ${km.get_pgp_short_key_id()}`,
                        `PGP fingerprint: ${km.get_pgp_fingerprint().toString("hex")}`,
                        `Signed on ${new Date(ds.sig.when_generated() * 1000).toUTCString()}`,
                        "----------------------------------\n"
                    ].join("\n");
                    text += unboxedLiterals.toString();
                    return text.trim();
                } else {
                    throw new OperationError("Could not identify a key manager.");
                }
            } else {
                throw new OperationError("The data does not appear to be signed.");
            }
        } catch (err) {
            throw new OperationError(`Couldn't verify message: ${err}`);
        }
    }

}

export default PGPDecryptAndVerify;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Read the interpolated err after the colon - it tells you which inner condition fired (no signature, no key manager, or a raw kbpgp error).
  2. Ensure both the signer's public key and the recipient's private key are correct and supplied.
  3. Confirm the input is an encrypted + signed message (not just encrypted or just signed).
  4. Decrypt/verify locally with GnuPG to validate the message and keys first.
Defensive patterns

Strategy: try-catch

Validate before calling

if (!/-----BEGIN PGP PUBLIC KEY BLOCK-----/.test(publicKey)) throw new Error('Signer public key missing');
if (!/-----BEGIN PGP PRIVATE KEY BLOCK-----/.test(privateKey)) throw new Error('Recipient private key missing');
if (!/-----BEGIN PGP MESSAGE-----/.test(signedMessage)) throw new Error('Input is not an armoured PGP message');

Try / catch

try {
    out = await chef.PGPDecryptAndVerify(msg, [pub, priv, pass]);
} catch (e) {
    if (e instanceof OperationError && /Couldn't verify message/.test(e.message)) {
        // e.message includes the inner cause - inspect the suffix
    } else throw e;
}

Prevention

When it happens

Trigger: kbpgp.unbox rejects (corrupt message, decryption failure, no matching key); or one of the inner guards (no signature, no key manager) fires. Any of these surfaces as this wrapped error.

Common situations: Wrong or missing keys; unsigned data fed to a verify operation; malformed armoured input; signing key absent from the keyring; mismatched operation-to-message type.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/144eac6b44484ba6. Report an issue: GitHub.