gchq/CyberChef · error · OperationError
failed to format datetime string ${datetime}
Error message
failed to format datetime string ${datetime} What it means
ParseX509CRL formats date fields (thisUpdate, nextUpdate, revocation dates, invalidity dates) via generalizedDateTimeToUTC, which expects a UTCTime/GeneralizedTime string matching ^\d{12,14}Z$. If jsrsasign hands back a date string not matching that shape, formatting aborts. The input comes from the parsed CRL, so this reflects a malformed or unexpected CRL/date encoding rather than user-typed text.
Source
Thrown at src/core/operations/ParseX509CRL.mjs:110
out += `\tCRL extensions:\n${formatCRLExtensions(crl.getParam().ext, 8)}\n`;
}
out += `Revoked Certificates:\n${formatRevokedCertificates(crl.getRevCertArray(), 4)}
Signature Value:\n${formatCRLSignature(crl.getSignatureValueHex(), 8)}`;
return out;
}
}
/**
* Generalized date time string to UTC.
* @param {string} datetime
* @returns UTC datetime string.
*/
function generalizedDateTimeToUTC(datetime) {
// Ensure the string is in the correct format
if (!/^\d{12,14}Z$/.test(datetime)) {
throw new OperationError(`failed to format datetime string ${datetime}`);
}
// Extract components
let centuary = "20";
if (datetime.length === 15) {
centuary = datetime.substring(0, 2);
datetime = datetime.slice(2);
}
const year = centuary + datetime.substring(0, 2);
const month = datetime.substring(2, 4);
const day = datetime.substring(4, 6);
const hour = datetime.substring(6, 8);
const minute = datetime.substring(8, 10);
const second = datetime.substring(10, 12);
// Construct ISO 8601 format string
const isoString = `${year}-${month}-${day}T${hour}:${minute}:${second}Z`;
View on GitHub (pinned to 4290ea7539)
Solutions
- Re-export the CRL in canonical PEM/DER from a trusted source (e.g. openssl crl).
- Verify the CRL with openssl first: 'openssl crl -in crl.pem -noout -text'.
- Check that the jsrsasign version bundled with your CyberChef build matches the one this op was written against.
- If the CRL is valid but the date shape differs, report it — the regex may need widening for that GeneralizedTime variant.
Defensive patterns
Strategy: try-catch
Validate before calling
function isValidGeneralizedTime(s) {
return /^\d{12,14}Z$/.test(s);
}
// Validate each date field before formatting if you control the CRL parsing pipeline. Type guard
function isGeneralizedTimeString(s) {
return typeof s === "string" && /^\d{12,14}Z$/.test(s);
} Try / catch
try {
return parseX509CRL.run(crlInput, [inputFormat]);
} catch (e) {
if (e.message.startsWith("failed to format datetime string")) {
// CRL date encoding is non-standard; validate with openssl externally
}
throw e;
} Prevention
- Validate CRLs with openssl crl before parsing.
- Keep the bundled jsrsasign version aligned with this op's expectations.
- Re-fetch CRLs from the CA distribution point rather than re-using stale copies.
When it happens
Trigger: A CRL whose thisUpdate/nextUpdate fields are not standard UTCTime (YYMMDDHHMMSSZ) or GeneralizedTime; a jsrsasign version that returns dates in a different format; a corrupt or hand-edited CRL; a revocation entry whose date field is malformed.
Common situations: Parsing a CRL produced by a non-RFC-conformant CA; jsrsasign upgrade changing date output; DER that was incorrectly re-encoded; partial/truncated CRL bytes fed in.
Related errors
- CRL entry extension object missing 'extname' key: ${ext}
- 'cRLNumber' CRL entry extension missing 'num' key: ${ext}
- invalid revoked certificate object, missing either serial nu
- 'cRLReason' CRL entry extension missing 'code' key: ${ext}
- PEM footer '${footer}' not found
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/9bba20712d1f113e.
Report an issue: GitHub.