Skip to content
getnextpdf.com

Core and general errors

These entries cover the core and general-purpose exceptions NextPDF raises. Most extend the base NextPdfException, which itself extends \RuntimeException and implements ContextAwareExceptionInterface. That interface exposes one method, getContext(): array, returning a flat snake_case map of primitives safe to serialize to a log or APM payload.

Catch the NextPdfException family with a single catch (NextPdfException $e). Add a catch (\RuntimeException $e) as well to cover the few low-level errors in this set that extend \RuntimeException directly (listed below). The base NextPdfException::getContext() returns an empty array; subclasses override it to add domain fields. Where a class does not override getContext(), it inherits the empty array and the diagnostic detail lives in the message and the typed getters instead.

Four types in this set do not extend NextPdfException: BlackPointCompensationUnsupportedException and UnsupportedSourceDocumentException extend \RuntimeException directly (catch them as \RuntimeException), and ComplianceViolation and RuleViolation are value objects, not exceptions — they are documented here because they model error and violation data the engine returns.

  • What it is. abstract base for the main NextPDF exception family across core and its extension packages. It extends \RuntimeException and implements ContextAwareExceptionInterface. Catching this single type intercepts the NextPdfException family; the few errors that extend \RuntimeException directly (listed above) need a \RuntimeException catch as well.
  • Context. The base getContext() returns an empty array. Subclasses override it to return domain-specific fields.
  • Recovery. Not thrown directly. Use it as the catch-all type; branch on the concrete subclass for specific handling.
  • When it is thrown. When a Config value or combination of values is invalid — a missing required setting, a mutually exclusive option, or a value outside its accepted range. This signals a developer error: the calling code supplied a configuration that must be corrected before retry. The message reports the key, the expected type or range, and the actual debug type of the supplied value.
  • Context. getContext() returns config_key, given_value, and expected_type. Typed getters: getConfigKey(), getGivenValue(), getExpectedType().
  • Recovery. Developer action: fix the named configuration key to a value of the expected type or range before calling NextPDF again.
  • When it is thrown. When a public API entry point is reached but its implementation is intentionally absent in the current release. Used for deprecated shims that exist to give pre-bisect callers a loud, actionable failure rather than a silent no-op. The message combines a machine-grep-able feature label and a followUp reference (defect ID, tracking anchor, or sprint name).
  • Context. Does not override getContext(), so it returns an empty array. The $feature and $followUp values are public readonly properties and are embedded in the message.
  • Recovery. Library-caller action: remove the call, or pin to a future release that lands the named follow-up.
  • When it is thrown. At Config build time (Config::validate()) when a CssFeatureFlags combination is internally inconsistent — one flag presupposes another that is disabled. The only forbidden combination today is layoutSubgrid = true with layoutGrid = false: a subgridded axis derives its grid lines from a parent grid container (CSS Grid Layout Module Level 2 §1), so subgrid without grid describes a grid that cannot exist. The check runs against resolved flags, so CssRenderingMode::Safe (which forces every Phase 4+ feature off) masks the combination rather than tripping it. Extends StrictModeViolation.
  • Context. getContext() merges the parent strict-mode fields (cssDeviation, excId, chunkSha256, location) with layoutGrid and layoutSubgrid booleans. The location is Config::validate() and cssDeviation encodes the flag pair.
  • Recovery. Library-caller action: enable layoutGrid alongside layoutSubgrid, or disable layoutSubgrid.
  • When it is thrown. At Config build time when a CssRenderingMode and CssLayoutMode pairing falls outside the compatible cells of the mode matrix. The only forbidden pairing today is CssRenderingMode::Safe + CssLayoutMode::Retained — Safe forces every Phase 4+ feature off, leaving retained-mode formatting contexts (Grid, Subgrid, @container) with no consumers, so the combination is rejected rather than allowed to degrade silently. Extends StrictModeViolation.
  • Context. getContext() merges the parent strict-mode fields with mode1 (the rendering-mode value) and mode2 (the layout-mode value). The cssDeviation encodes the mode pair; location is Config::validate().
  • Recovery. Library-caller action: choose Safe + Streaming for rollback, or a non-Safe rendering mode (Normal / Strict / Audit) with Retained for Grid / Subgrid / Container Queries.
  • When it is thrown. abstract base for any spec-deviation exception thrown under CssRenderingMode::Strict. In strict mode, any detected CSS deviation not linked to a registered EXC-NNN exception entry throws an instance of this class (or a subclass) at the detection point. Not thrown directly; see IncompatibleFeatureFlagsException and IncompatibleRenderingModeException.
  • Context. getContext() returns the four ADR-023 fields: cssDeviation (short label for the deviating construct), excId (registry identifier when registered, else null), chunkSha256 (spec-citation chunk hash when known, else null), and location (caller-readable origin, else null).
  • Recovery. Library-caller action: register the deviation as a new signed-off EXC-NNN entry, or fix the renderer to remove the deviation.
  • When it is thrown. When HTML input parsing or DOM construction fails: invalid charset declarations, input-size-limit violations, excessive nesting depth, element-count overflows, and table-structure errors such as a row-count maximum. CSS-specific resource exhaustion is reported instead by CssParserLimitExceededException and CssResolutionBudgetExceededException.
  • Context. getContext() returns html_snippet (a short, truncated excerpt of the offending HTML), position (byte offset, or -1 if unknown), and rule (the violated parser constraint). Typed getters: getHtmlSnippet(), getPosition(), getRule().
  • Recovery. Developer action: simplify the HTML input or adjust the parser limits.
  • When it is thrown. When CSS input exceeds a configured parser safety limit. Two categories are covered through the named constructors: forByteLimit() (stylesheet too large for safe regex processing) and forNestingDepth() (CSS nesting recursion too deep). Both messages name the actual value and the limit.
  • Context. getContext() returns limit_type (byte or nesting_depth), actual, and limit.
  • Recovery. Developer action: split the stylesheet into smaller sheets, or reduce nesting depth, or raise the configured limit.
  • When it is thrown. When CSS :has() resolution exceeds its traversal budget. The two-pass :has() resolver enforces a strict node-visit budget to prevent pathological selectors from causing quadratic document walks; once the total visit count exceeds the limit, the stylesheet is rejected as too complex. The message names the visit count and the budget.
  • Context. getContext() returns visits and budget. Typed getters: getVisits(), getBudget().
  • Recovery. Developer action: reduce selector complexity, or raise the configured budget.
  • When it is thrown. When a font file cannot be located or read at the file-system level: the requested family or path does not exist, is not readable, or the configured fonts directory is inaccessible. The font data may be valid — this signals only that it cannot be reached. The message lists the searched paths.
  • Context. getContext() returns font_name, search_paths (a list), and fallback_attempted (a bool). Typed getters: getFontName(), getSearchPaths(), wasFallbackAttempted().
  • Recovery. Developer action: verify the font path. Infrastructure action: fix file permissions on the font file or directory.
  • When it is thrown. When a font file is found but its contents are not usable: it is corrupt, in an unsupported format, or missing required tables. Covers structural validation failures during TrueType, Type 1, CFF, and OpenType parsing — truncated headers, invalid table directories, missing mandatory tables (head, hhea, OS/2), unpacking errors, and size violations. The message names the file and the parse error.
  • Context. getContext() returns font_file and parse_error. Typed getters: getFontFile(), getParseError().
  • Recovery. Developer action: replace the font file with a valid one.
  • When it is thrown. When an image cannot be decoded, is in an unsupported format, or fails GD/Imagick processing: unrecognizable magic bytes, corrupt JPEG data, unsupported MIME types, file-size-limit violations, and GD resource allocation failures. The image was accessible but its pixel data could not be extracted for embedding.
  • Context. getContext() returns image_path (empty for inline data), format (detected or expected, e.g. jpeg, png, unknown), and operation (e.g. decode, resize, embed). Typed getters: getImagePath(), getFormat(), getOperation().
  • Recovery. Developer action: supply a valid, supported image file.
  • When it is thrown. When FlateDecode (zlib) compression or decompression fails — gzcompress/gzuncompress failures on content streams, font data, page content, attachment data, and cross-reference streams. Typically a corrupt input stream, insufficient memory, or a missing zlib extension.
  • Context. getContext() returns algorithm (filter name, e.g. FlateDecode, LZWDecode) and stream_length (byte length, or -1 if unknown). Typed getters: getAlgorithm(), getStreamLength().
  • Recovery. Infrastructure action: verify ext-zlib is loaded and memory is sufficient.
  • When it is thrown. When PDF serialization, linearization, or I/O output fails: PdfWriter stream-writing errors, cross-reference table corruption, header/trailer generation failures, object-reference resolution failures, file write errors, and output-buffer overflows. A valid in-memory document could not be serialized to a valid byte stream. The message names the stage.
  • Context. getContext() returns output_path (empty for string output) and writer_state (the stage, e.g. header, body, xref, trailer). Typed getters: getOutputPath(), getWriterState().
  • Recovery. Infrastructure action: check disk space, file permissions, and the output stream.
  • When it is thrown. When page-layout constraints cannot be satisfied: column-layout violations (insufficient width, invalid column count), content overflow beyond page boundaries, and margin conflicts. The requested layout is geometrically impossible for the given page dimensions and content. The message names the page number when known and the violated constraint.
  • Context. getContext() returns page_number (one-based, or 0 if unknown) and constraint. Typed getters: getPageNumber(), getConstraint().
  • Recovery. Developer action: adjust page size, margins, column settings, or content.
  • When it is thrown. When a PDF template import or reuse operation fails in TemplateManager: invalid template state transitions (beginning or ending templates out of sequence), referencing a non-existent template, and stream compression failures during template serialization. The message names the operation and the template id when assigned.
  • Context. getContext() returns template_id (empty if not yet assigned) and operation (e.g. begin, end, use, serialize). Typed getters: getTemplateId(), getOperation().
  • Recovery. Developer action: fix the template usage sequence or the source PDF.
  • When it is thrown. When a ContentStreamBuilder detects an imbalanced operator pair at stream close (or mid-stream when invariants are asserted eagerly). It captures the depth counters that failed the balance invariant so logging can identify which emitter leaked a q, BT, or BMC without its matching Q, ET, or EMC. Per ISO 32000-2:2020 §8.4.2 (graphics-state stack), §9.4.1 (text objects), and §14.6 (marked content).
  • Context. getContext() returns graphics_depth, text_block_depth, marked_content_depth, and offending_operator. Typed getters: getGraphicsDepth(), getTextBlockDepth(), getMarkedContentDepth(), getOffendingOperator().
  • Recovery. Developer action: locate the emitter that opened a construct without closing it.
  • When it is thrown. When a PDF content stream closes with unbalanced q/Q operators. ISO 32000-2:2020 §8.4.2 requires each graphics-state save (q) to be matched by exactly one restore (Q) before the stream ends; imbalance leaks transform, clipping path, colours, and rendering intent into subsequent pages or Form XObjects. Raised only when strict graphics-state checking is enabled (NEXTPDF_GFXSTATE_STRICT=1); in relaxed mode a warning is emitted via trigger_error() instead.
  • Context. getContext() returns save_depth (positive for too many saves, negative for too many restores). Typed getter: getSaveDepth().
  • Recovery. Developer action: locate the unmatched save()/restore() pair.
  • When it is thrown. When ConicGradientRenderer::render() is invoked without a Shading-resource registry context. The v10.0.0 breaking change removed the prior implicit-marker-map surrogate path: callers must construct the renderer with a ShadingResourceRegistryInterface so the /ShadingType 4 indirect object is registered against the page’s Shading-resource subdictionary (ISO 32000-2 §8.7.4.2 / §8.7.4.3). The message names the caller context and points at the v9.x→v10.0 migration note.
  • Context. getContext() returns context (a short caller-context label, e.g. ConicGradientRenderer::render).
  • Recovery. Library-caller action: wire a Shading-resource registry instance into the renderer constructor before calling render().
  • When it is thrown. When the v2 three-pass Linearizer detects that its MEASURE → PLACE → FILL assertions were violated: a Pass 3 byte count not matching the Pass 1 predicted file length (offset drift), a linearization dictionary placeholder too small for the serialized width, or a /H [offset length] hint-stream offset not matching the final output. Surfacing this rather than emitting a broken PDF is a stated safety guarantee.
  • Context. getContext() returns invariant (the violated invariant name), expected, actual, and delta (the signed difference). Typed getters: getInvariant(), getExpectedValue(), getActualValue().
  • Recovery. Maintainer action: file a bug report — these invariants should hold for all well-formed inputs. Capture the chained previous exception.
  • When it is thrown. When the linearizer feature flag is set to a backend that is intentionally disabled. Currently raised only for linearizerVersion === 'v1-noop', the emergency-downgrade setting that rejects all linearization attempts at runtime without a code change or redeploy — useful for kill-switching Fast Web View in production.
  • Context. getContext() returns reason (a short human-readable explanation). Typed getter: getReason().
  • Recovery. Operator / release-engineering action: adjust the configuration or upgrade to a fixed backend version.
  • When it is thrown. When a requested feature cannot be emitted without breaking the document’s declared ISO conformance contract, and the engine fails closed rather than write a non-conformant object. The canonical trigger is a multimedia Screen annotation or Rendition action (ISO 32000-2:2020 §12.5.6.18 / §13.2) under a PDF/A archival profile, which every PDF/A part forbids (ISO 19005 series) — the file would fail veraPDF validation, so the engine refuses up front.
  • Context. getContext() returns conformance_mode (the declared mode, e.g. pdfa4) and feature (the rejected feature, e.g. Screen annotation). Both are public readonly properties. The reason is the exception message.
  • Recovery. Developer action: drop the multimedia call for archival output, or target a non-archival conformance profile (default ConformanceMode::Plain).
  • When it is thrown. When a PDF/R-1 (ISO 23504-1:2020) conformance invariant is violated, either at value-object construction (the PdfRStrip, PdfRPage, PdfRDocument profiles) or at validator time (PdfRValidator). It captures the offending normative clause and a one-line violation description so audit consumers can route findings to the correct §6 sub-clause without parsing free text.
  • Context. getContext() returns standard (always ISO 23504-1:2020), clause (the clause path, e.g. 6.6.1), and violation. Typed getters: getClause(), getViolation().
  • Recovery. Developer action: correct the rejected input or rebuild the document to conform to the cited clause.
  • When it is thrown. When barcode generation fails due to invalid data or encoding errors across all supported symbologies (Code 39/128, UPC-A/E, EAN-8/13, Interleaved/Standard 2-of-5, POSTNET, PLANET, MSI, ISBN, ISSN, QR Code, PDF417, DataMatrix, JabCode), and GD rendering failures during image creation. The barcode value is excerpt-capped to 128 bytes in the message and context — over-long or binary payloads are stored truncated with a ... (<N> bytes, truncated) marker so they cannot be copied whole into a log.
  • Context. getContext() returns barcode_type (symbology, e.g. QRCODE, EAN13, CODE128) and value (the truncated value). Typed getters: getBarcodeType(), getValue().
  • Recovery. Developer action: correct the barcode data or the symbology selection.
  • When it is thrown. From BarcodeEncoderRegistry when the requested encoder type is unknown or its capability gate is closed. It also implements PSR-11 Psr\Container\NotFoundExceptionInterface, so the registry is a standards-conforming container. The message names the symbology and the reason.
  • Context. Does not override getContext(), so it returns an empty array. The type and reason are available through the getType() and getReason() getters and in the message.
  • Recovery. Developer action: register the encoder, or install the package that provides it (for example nextpdf/pro for Micro QR / DotCode / HanXin / JabCode).
  • When it is thrown. When PDF encryption or decryption fails: AES-256-CBC encrypt/decrypt failures, OpenSSL errors, invalid IV sizes, hash-computation failures, and UE/OE value-computation errors. Typically a missing or misconfigured OpenSSL extension, invalid key material, or corrupted encrypted data. The message names the operation and the algorithm.
  • Context. getContext() returns algorithm (e.g. AES-256-CBC) and operation (e.g. encrypt, decrypt, key_derivation). Typed getters: getAlgorithm(), getOperation().
  • Recovery. Infrastructure action: ensure OpenSSL is available and correctly configured. See Encryption and permissions.
  • When it is thrown. When a cryptographic algorithm cannot be executed in the current runtime: a required PHP extension is unavailable, the underlying library lacks the primitive, the bundled hash extension cannot synthesise a SHAKE/XOF variant, or the algorithm is not registered in the SignatureAlgorithmRegistry. The engine must not silently degrade to a weaker primitive, so it surfaces this instead. The static factory nonFipsHostUnderFipsProfile() raises it (with algorithm identifier regulatory-profile:fips) when RegulatoryProfile::FIPS is selected but a FIPS-validated OpenSSL provider cannot be confirmed (both FIPS_ABSENT and INDETERMINATE fail closed).
  • Context. getContext() returns algorithm (name or OID, e.g. shake256, Ed25519, AES-256-GCM) and reason (operator-actionable). Typed getters: getAlgorithm(), getReason().
  • Recovery. Operator action: install the missing extension or upgrade the runtime; for the FIPS gate, install a FIPS-validated OpenSSL build or set NEXTPDF_FIPS_MODE explicitly. Developer action: register a custom algorithm descriptor via SignatureAlgorithmRegistry::register().
  • When it is thrown. When a digital signature operation fails: certificate and private-key handling (PKCS#12 parsing, PEM/DER decoding, X.509 validation), PKCS#7/CMS construction, ECDSA signature format, container-size violations, DER encoding, and PAdES orchestration. TSA-specific errors are reported by the more specific TsaException instead. Prefer the typed named factories over the positional constructor; each binds the root cause to the message tail. Examples: ltvCapabilityMissing() (B-LT/B-LTA needs nextpdf/enterprise), tsaRequired() / tsaUrlEmpty() / tsaEmptyToken(), httpClientMissing(), hsmSignerMissing() / hsmSignatureEmpty(), signatureContentsNotFound() / signatureContentsPaddingCorrupt(), unexpectedKeyType(), pemDecodingFailed(), the Ed25519 family (ed25519SignatureMalformed(), ed25519RoundTripVerifyFailed(), ed25519KeyParseFailed(), ed25519SeedInvalid(), ed25519SecretKeyMalformed(), ed25519PublicKeyInvalid()), documentTimestampNotEmitted(), algorithmPolicyRejected(), digestOnlyAlgorithmRefused(), encryptedLtvUnsupported(), incrementalUpdateWriterMissing(), and the OCSP-status pair nonSuccessfulOcspResponseStatus() / reservedOcspResponseStatus() (RFC 6960 §4.2.1). These factories fail closed rather than emit a silently down-levelled signature.
  • Context. getContext() returns cert_info (subject DN or thumbprint, or empty), signature_level (the PAdES level attempted, e.g. B-B, B-T, B-LT, B-LTA), and detail (the actionable diagnostic, empty for the legacy positional constructor). Typed getters: getCertInfo(), getSignatureLevel(), getDetail().
  • Recovery. Developer action: fix certificate/key configuration. For capability-missing factories, install the named package. See Signature and timestamp failures for per-factory symptom-and-resolution entries.

BlackPointCompensationUnsupportedException

Section titled “BlackPointCompensationUnsupportedException”
  • When it is thrown. From NullBlackPointCompensationTransform::transform() when a caller asks the null adapter to apply a non-Default ISO 18619 black-point compensation transform. The null adapter is the safe fallback for environments without a colour-management backend; producing a transformed sample without a real colour-management module would silently misreport the conversion. Unlike most entries here, this extends \RuntimeException directly, not NextPdfException, so existing catch (\RuntimeException) paths keep working.
  • Context. No getContext(); it is a plain \RuntimeException. The detail is in the message.
  • Recovery. Developer action: register a real BlackPointCompensationTransform (LittleCMS, Argyll, pure-PHP), or restrict /UseBlackPtComp to BlackPointCompensation::Default.
  • When it is thrown. When a source document cannot be safely copied into a merge/split output and the operation fails closed rather than emit a corrupt or security-compromised result. Use the named factories: encrypted() (ISO 32000-2 §7.6 — content cannot be copied without the key), signed() (§12.8 — copying pages would invalidate the signature byte range), unsupportedStreamFilter() (a filter the object-graph reader cannot round-trip), multipleInteractiveForms() (a documented limitation: more than one source carries a non-empty /AcroForm, §12.7), and splitWithInteractiveForm() (a documented limitation: page-subsetting a form-bearing source would orphan widgets). Extends \RuntimeException directly, not NextPdfException.
  • Context. No getContext(); it is a plain \RuntimeException. The cause and affected object number are named in the message.
  • Recovery. Developer action: decrypt the source first or supply the key; for signed sources, sign after merging instead; for multi-form merges, flatten or remove the form fields of all but one source; for form-bearing splits, flatten the form before splitting.
  • When it is thrown. From Bcp47Validator::validate() when a candidate language tag is malformed under RFC 5646 §2.1 ABNF, or fails the curated registry lookup. Domain-specific to BCP-47 / ISO 14289-2:2024 §8.4.4, distinct from InvalidConfigException so callers downstream of the accessibility seam can catch a narrow type. The predicate pair Bcp47Validator::isWellFormed() / isValid() remains the backward-compatible return-value surface for callers that prefer branching over exceptions.
  • Context. getContext() returns tag (the candidate exactly as supplied) and reason (a stable machine-readable rejection code, e.g. empty-string, well-formed-shape, unregistered-primary, duplicate-variant). Typed getters: getTag(), getReason().
  • Recovery. Developer action: correct the language tag to a well-formed, registered BCP-47 tag. See Fonts and tagging.
  • When it is thrown. When an interactive form field would rely on a synthetic (non-author-supplied) accessible name while producing a PDF/UA document with strict accessible-field-name enforcement enabled. Default PDF/UA output emits a synthetic fallback name into the widget /Contents so a field is never un-named; strict mode instead requires the author to supply a meaningful name (a tooltip, or a caption for an action-less push button) so screen-reader users get a real description (ISO 14289-2:2024 §8.10.2).
  • Context. Does not override getContext(), so it returns an empty array. The $fieldId is a public readonly property; the reason is the message.
  • Recovery. Developer action: supply a tooltip / accessible name for the named field before producing a strict PDF/UA document, or disable strict mode. See PDF/A and PDF/UA validation.
  • When it is thrown. From VendorExtensionRegistry::register() when a caller re-registers a known PDF developer-extension vendor prefix (ISO 32000-2:2020 §7.12.1) with a description that disagrees with the already-registered metadata. Descriptors are append-only and conflict-detected; the typed exception replaced a generic \RuntimeException so callers can catch this specific class.
  • Context. getContext() returns prefix, existing_description, and attempted_description. Typed getters: getPrefix(), getExistingDescription(), getAttemptedDescription().
  • Recovery. Developer action: register the prefix with the existing description, or use a distinct prefix; do not overwrite registered metadata.
  • When it is thrown. When audit-export bundle assembly, traceability-matrix generation, or schema projection fails at runtime. Covers I/O against claims.json / manifest.json, JSON encode/decode of the canonical bundle, and schema-version mismatch on the AuditExporter::projectToV1() backward-compat path. The message names the stage, the artefact when known, and the detail.
  • Context. getContext() returns stage (e.g. read_claims, encode_bundle, project_v1), detail, and artefact (path or schema_version that triggered the failure). Typed getters: getStage(), getDetail(), getArtefact().
  • Recovery. Compliance / DevOps action: verify input artefact paths, regenerate claims.json from a clean run, or rebuild the manifest before reattempting export.

These are not exceptions. They are immutable value objects the engine returns to describe an individual violation; they carry no getContext().

  • What it is. A final readonly value object representing one rule failure reported by an external validator (veraPDF or equivalent), including the ISO clause reference and the location within the PDF structure.
  • Fields. Public readonly properties: ruleId (validator rule identifier, e.g. 6.1.2-1), clause (ISO clause reference, e.g. ISO 19005-1:2005, 6.1.2), severity (e.g. error, warning), location (object path within the PDF structure), and message (human-readable description).
  • Use. Inspect the collection returned by a compliance validator; route or display each entry by severity and clause. See PDF/A and PDF/UA validation.
  • What it is. A final readonly value object representing one Schematron / EN 16931 business-rule violation, returned by SchematronRunnerInterface::runRules() and aggregated inside ValidationResult::$ruleViolations. Stability is experimental.
  • Fields. Public readonly properties: ruleId (EN 16931 identifier such as BR-{n}, BR-CO-{n}, BR-CL-{n}, BR-DEC-{n}, or a tier-specific pack), severity (a RuleSeverity enum), message (rule text, en-GB), xpath (XPath into the embedded XML, null for document-wide rules), and semanticPath (dot-notation BG/BT path such as BG-22.BT-106, null for structural violations).
  • Use. Inspect the collection on the validation result; route or display each entry by severity, ruleId, and locator.