mozilla/pdf.js · error · FormatError
Optional content properties malformed.
Error message
Optional content properties malformed.
What it means
Thrown by parseMarkedContentProps() when the properties operand of a marked-content operator (e.g. /OC inside a BDC/DP marked-content sequence) is neither a Name (referencing a /Properties resource entry) nor a Dictionary (an inline OCG/OCMD dictionary). Optional Content (layers) require one of these two forms; any other type is malformed. The guard precedes the .get('Type') access that would otherwise throw a TypeError.
Source
Thrown at src/core/evaluator_utils.js:91
currentResult.push(nestedResult);
// Recursively parse a subarray.
_parseVisibilityExpression(xref, object, nestingCounter, nestedResult);
} else if (raw instanceof Ref) {
// Reference to an OCG dictionary.
currentResult.push(raw.toString());
}
}
}
function parseMarkedContentProps(xref, contentProperties, resources) {
let optionalContent;
if (contentProperties instanceof Name) {
const properties = resources.get("Properties");
optionalContent = properties.get(contentProperties.name);
} else if (contentProperties instanceof Dict) {
optionalContent = contentProperties;
} else {
throw new FormatError("Optional content properties malformed.");
}
const optionalContentType = optionalContent.get("Type")?.name;
if (optionalContentType === "OCG") {
return {
type: optionalContentType,
id: optionalContent.objId,
};
} else if (optionalContentType === "OCMD") {
const expression = optionalContent.get("VE");
if (Array.isArray(expression)) {
const result = [];
_parseVisibilityExpression(xref, expression, 0, result);
if (result.length > 0) {
return {
type: "OCMD",
expression: result,
};View on GitHub (pinned to 5903d58d58)
Solutions
- Re-export the PDF ensuring the optional-content properties operand is either a Name referencing /Properties or an inline OCG/OCMD dictionary.
- Flatten layers before publishing (Acrobat 'Flatten' or Ghostscript) to eliminate the OC marked content entirely.
- Isolate the page with per-page try/catch and continue rendering others.
- If authoring with layers, validate each BDC/DP /OC operand against the PDF spec section 8.11 before output.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await page.render({ canvasContext, viewport });
} catch (e) {
if (e.name === 'FormatError' && /Optional content properties malformed/.test(e.message)) {
// bad OC marked-content operand — skip or render without layer info
} else throw e;
} Prevention
- Flatten optional-content layers (Acrobat 'Flatten' or Ghostscript) before publishing if layers are not required.
- When authoring OC, ensure BDC/DP /OC operands are either a Name (Properties ref) or an inline OCG/OCMD dictionary.
- Validate the OC structure against PDF spec section 8.11 in a pre-publish lint step.
When it happens
Trigger: A content stream emitting 'BDC' or 'DP' with an optional-content properties operand that is a string, number, null, array, or stream. Fires during operator-list preprocessing when the marked-content tag is /OC and parseMarkedContentProps is invoked. Also possible if /OCMD or /OCG inline dictionaries are malformed upstream.
Common situations: PDFs with layers (OCG/OCMD) produced by generators that wrote the properties operand incorrectly, or PDFs damaged in their optional-content region. Common in CAD-exported or layer-heavy engineering PDFs where the OC structure is complex and buggy.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid entry in 'Differences' array: ${data}
- Encoding is not a Name nor a Dict
- Max size of CID is 65,535
- invalid font Subtype
- Descendant fonts are not specified
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/2a797e14c0e2ad0a.
Report an issue: GitHub.