gchq/CyberChef · error · OperationError
'cRLReason' CRL entry extension missing 'code' key: ${ext}
Error message
'cRLReason' CRL entry extension missing 'code' key: ${ext} What it means
For a CRL entry extension with extname 'cRLReason', formatCRLEntryExtensions requires a 'code' key (the numeric reason code). If absent the op cannot render the revocation reason and throws. This is an assertion about jsrsasign's parsed cRLReason structure inside a revoked-cert entry.
Source
Thrown at src/core/operations/ParseX509CRL.mjs:318
8: "Remove From CRL",
9: "Privilege Withdrawn",
10: "AA Compromise",
};
const holdInstructionOIDToName = {
"1.2.840.10040.2.1": "Hold Instruction None",
"1.2.840.10040.2.2": "Hold Instruction Call Issuer",
"1.2.840.10040.2.3": "Hold Instruction Reject",
};
exts.forEach((ext) => {
if (!Object.hasOwn(ext, "extname")) {
throw new OperationError(`CRL entry extension object missing 'extname' key: ${ext}`);
}
switch (ext.extname) {
case "cRLReason":
if (!Object.hasOwn(ext, "code")) {
throw new OperationError(`'cRLReason' CRL entry extension missing 'code' key: ${ext}`);
}
out += `X509v3 CRL Reason Code:
${Object.hasOwn(crlReasonCodeToReasonMessage, ext.code) ? crlReasonCodeToReasonMessage[ext.code] : `invalid reason code: ${ext.code}`}\n`;
break;
case "2.5.29.23": // Hold instruction
out += `Hold Instruction Code:\n\t${Object.hasOwn(holdInstructionOIDToName, ext.extn.oid) ? holdInstructionOIDToName[ext.extn.oid] : `${ext.extn.oid}: unknown hold instruction OID`}\n`;
break;
case "2.5.29.24": // Invalidity Date
out += `Invalidity Date:\n\t${generalizedDateTimeToUTC(ext.extn.gentime.str)}\n`;
break;
default:
out += `${ext.extname}:\n`;
out += `\tUnsupported CRL entry extension. Try openssl CLI.\n`;
break;
}
});
return chop(out);View on GitHub (pinned to 4290ea7539)
Solutions
- Inspect the entry's reason code with openssl.
- Re-fetch the CRL from the CA distribution point.
- Verify the bundled jsrsasign version.
- Report a conformant CRL that the op rejects so the key check can be relaxed.
Defensive patterns
Strategy: try-catch
Validate before calling
const crl = new r.X509CRL(input);
const reasonExts = (crl.getRevCertArray() || []).flatMap(rc => (rc.ext || []).filter(e => e.extname === "cRLReason"));
if (reasonExts.some(e => !Object.hasOwn(e, "code"))) {
throw new Error("A cRLReason entry extension is missing 'code'");
} Type guard
function isValidCrlReasonExtension(ext) {
return ext.extname !== "cRLReason" || Object.hasOwn(ext, "code");
} Try / catch
try {
return parseX509CRL.run(crlInput, [inputFormat]);
} catch (e) {
if (e.message.includes("'cRLReason' CRL entry extension missing 'code'")) {
// non-standard reason-code encoding; validate with openssl
}
throw e;
} Prevention
- Validate CRLs with openssl crl -text.
- Keep jsrsasign version aligned.
- Re-fetch CRLs from a trusted source.
When it happens
Trigger: A revoked-cert entry with a cRLReason extension (OID 2.5.29.21) whose parsed object lacks 'code'; malformed reason-code value; jsrsasign returning a different key name.
Common situations: Non-standard reason-code encoding; corrupt CRL; jsrsasign version skew.
Related errors
- CRL entry extension object missing 'extname' key: ${ext}
- 'cRLNumber' CRL entry extension missing 'num' key: ${ext}
- failed to format datetime string ${datetime}
- invalid revoked certificate object, missing either serial nu
- PEM footer '${footer}' not found
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/42981104d7a6e973.
Report an issue: GitHub.