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

  1. Re-export the PDF ensuring the optional-content properties operand is either a Name referencing /Properties or an inline OCG/OCMD dictionary.
  2. Flatten layers before publishing (Acrobat 'Flatten' or Ghostscript) to eliminate the OC marked content entirely.
  3. Isolate the page with per-page try/catch and continue rendering others.
  4. 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

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

Related errors


AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13). Data as JSON: /api/errors/2a797e14c0e2ad0a. Report an issue: GitHub.