CheckFileCompliance
Compliance, Document inspection
Description
Reads an external PDF file and validates it against a chosen ISO compliance standard. The returned value is either zero (file passes the chosen test cleanly) or a non-zero StringListID handle that lists every issue detected. Each entry in the list is a short code, a colon, and a human-readable message — exactly the same code format used by GetPDFUADiagnostics. Enumerate the result with GetStringListCount and GetStringListItem.
The PDF/A test covers all six conformance modes (PDF/A-1a, PDF/A-1b, PDF/A-2a, PDF/A-2b, PDF/A-3a, PDF/A-3b) and reads the pdfaid:part/pdfaid:conformance XMP entries to decide which rule set to apply.
The PDF/UA-1 test (added in v3.56.0) checks an external PDF against ISO 14289-1 and emits diagnostic codes in the 10xxx range so they remain visually separate from the PDF/A 00xxx codes.
Syntax
Delphi
function TPDFlib.CheckFileCompliance(const InputFileName, Password: WideString; ComplianceTest, Options: Integer): Integer;ActiveX
Function PDFlib::CheckFileCompliance(InputFileName As String, Password As String, ComplianceTest As Long, Options As Long) As LongDLL
int DLCheckFileCompliance(int InstanceID, wchar_t * InputFileName, wchar_t * Password, int ComplianceTest, int Options);Parameters
| InputFileName | Full path of the PDF file to validate. The file is opened read-only and is not modified. |
|---|---|
| Password | Password used to open the file. Pass an empty string for unencrypted documents. Note that an encrypted document fails the PDF/A test (code 00006) regardless of whether the correct password is supplied — PDF/A forbids encryption. |
| ComplianceTest | The standard to check against. 1 — PDF/A (ISO 19005-1/-2/-3, all six conformance levels). 2 — PDF/UA-1 (ISO 14289-1:2014, accessible PDF). |
| Options | Bit flags that modify the test. 0 — Default: report every issue found in the document. 1 — Stop after the first issue and return immediately. Useful when the caller only needs a pass/fail signal. |
Return values
| 0 | The file is conformant with the chosen standard. |
|---|---|
| Non-zero | A StringListID handle whose entries describe each detected non-conformance. The handle remains valid until the document is closed or ReleaseStringList is called. |
PDF/A issue codes (ComplianceTest = 1)
| 00002 | PDF version exceeds the maximum allowed by the conformance level (PDF/A-1 caps at 1.4; PDF/A-2 and PDF/A-3 cap at 1.7). The detail line names the offending version and the allowed maximum. |
|---|---|
| 00003 | The Catalog contains /OCProperties (optional content / layers), forbidden by PDF/A-1. PDF/A-2 and PDF/A-3 permit layers and do not trigger this check. |
| 00005 | The XMP pdfaid:part+pdfaid:conformance pair is missing, malformed, or contains a value outside the legal set 1A, 1B, 2A, 2B, 3A, 3B. The library cannot determine which rule set to apply, so this is reported as a fatal issue regardless of Options. |
| 00006 | The document is encrypted. PDF/A forbids encryption in every part. |
| 00007 | The Catalog has no /OutputIntents entry. All PDF/A parts require an output intent so that the rendering color space is unambiguously defined. |
| 00011 | The Catalog has no /MarkInfo entry. Required only for a-level conformance (PDF/A-1a, 2a, 3a) — tagged PDF must declare itself. |
| 00012 | The Catalog has no /StructTreeRoot entry. Required only for a-level conformance. A tagged-PDF document must have a logical structure tree. |
PDF/UA-1 issue codes (ComplianceTest = 2)
| 10001 | The XMP metadata stream does not contain pdfuaid:part, or the value is not 1. ISO 14289-1 §5 requires a conforming file to identify itself via this property; ISO 14289-1 §6.2 forbids reporting conformance without it. |
|---|---|
| 10002 | The document Catalog has no /Metadata stream. A PDF/UA-1 conformance claim is recorded inside this stream; without it the file cannot announce itself as accessible. |
| 10003 | The Catalog /MarkInfo dictionary is missing or /Marked is not true. ISO 14289-1 §7.1 requires every conforming file to declare itself as tagged so that assistive technology can rely on the structure tree. |
| 10004 | The Catalog has no /StructTreeRoot entry. A PDF/UA-1 file must include a logical structure tree describing the document's reading order and semantics. |
| 10005 | The /ViewerPreferences dictionary is missing or its /DisplayDocTitle entry is not true. ISO 14289-1 §7.1 requires conforming readers to surface the document title in their window chrome instead of the file name. |
| 10006 | The Catalog /Lang entry is missing or empty. ISO 14289-1 §7.2 (referring to ISO 32000-1 §14.9.2) requires every conforming file to declare its natural language so screen readers select the correct voice and pronunciation rules. |
| 10007 | The XMP metadata stream does not carry a non-empty Dublin Core dc:title. ISO 14289-1 §7.1 requires "a dc:title entry which clearly identifies the document". |
| 10008 | The /MarkInfo dictionary has /Suspects set to true. ISO 14289-1 §7.1: files claiming PDF/UA conformance must have a Suspects value of false — a true value marks the tagging as known to contain errors. |
| 10009 | The document /RoleMap remaps one or more standard structure types. ISO 14289-1 §7.1: standard tags defined in ISO 32000-1 §14.8.4 (P, H1..H6, Figure, Table, etc.) shall not be remapped. The detail line names the first standard tag that was remapped. |
| 10010 | The file is encrypted, but bit 10 of the encryption /P permission key (mask 512, "Extract for accessibility") is not set. ISO 14289-1 §7.16 requires every encrypted conforming file to permit accessibility extraction so assistive technology can reach the content. |
| 10011 | A dynamic XFA form was detected: the XFA XDP packet contains <dynamicRender>required</dynamicRender>. ISO 14289-1 §7.15 forbids dynamic XFA forms in conforming files; static XFA is permitted. |
| 10012 | A Reference XObject (Form XObject carrying a /Ref entry) was detected. ISO 14289-1 §7.20 forbids reference XObjects because they let one PDF embed another by reference without exposing the referenced content to assistive technology. |
| 10013 | One or more TrapNet annotations were detected. ISO 14289-1 §7.18.2 explicitly forbids TrapNet in conforming files. The detail line reports how many annotations were found. |
| 10014 | One or more pages carry annotations but do not set /Tabs /S in their page dictionary. ISO 14289-1 §7.18.3 requires tab order on such pages to follow the structure tree, which is signalled by /Tabs /S. The detail line reports the count of offending pages. |
| 10015 | One or more Link annotations lack a non-empty /Contents alternate description. ISO 14289-1 §7.18.5 requires each Link annotation to carry an accessible description so that screen readers can announce the link target. The detail line reports the count of offending Link annotations. |
| 10016 | One or more embedded-file FileSpec dictionaries are missing the /F file-name key. ISO 14289-1 §7.11 requires every embedded-file FileSpec to carry both /F and /UF. |
| 10017 | One or more embedded-file FileSpec dictionaries are missing the /UF Unicode file-name key. ISO 14289-1 §7.11 requires every embedded-file FileSpec to carry both /F and /UF. |
| 10018 | One or more optional-content configuration dictionaries are missing a non-empty /Name text string. ISO 14289-1 §7.10 requires every OCG configuration dictionary (the default D entry plus every dictionary in OCProperties/Configs) to carry a non-empty /Name. |
| 10019 | One or more optional-content configuration dictionaries contain the forbidden /AS key. ISO 14289-1 §7.10 explicitly forbids /AS in any OCG configuration dictionary to prevent automatic state adjustments driven by usage information. |
| 10020 | One or more non-Standard-14 fonts referenced by the document do not embed their font program (no FontFile, FontFile2, or FontFile3 entry on the FontDescriptor). ISO 14289-1 §7.21.4.1 requires every font used for rendering to embed its program. Type 3 fonts skip this check because their glyphs are inline CharProcs. |
| 10021 | One or more CIDFontType2 descendants are missing the /CIDToGIDMap entry. ISO 14289-1 §7.21.3.2 requires every embedded Type 2 CIDFont to carry /CIDToGIDMap (either as a stream mapping CIDs to glyph indices, or as the name Identity). |
| 10022 | One or more Standard 14 fonts (Helvetica, Times, Courier, Symbol, ZapfDingbats and their bold / oblique variants) are referenced without an embedded font program. ISO 14289-1 §7.21.4 NOTE 5 makes clear there is no exemption from embedding for the 14 standard Type 1 fonts. |
| 10023 | One or more fonts are missing a /ToUnicode CMap and do not match the §7.21.7 exemption list. The exemption list covers the predefined MacRomanEncoding / MacExpertEncoding / WinAnsiEncoding, Type 0 fonts whose descendant CIDFont uses the Adobe GB1 / CNS1 / Japan1 / Korea1 character collections, and non-symbolic TrueType fonts. |
| 10024 | The first heading element in document order is not H1 (or the strongly-structured H). ISO 14289-1 §7.4.2: "If any heading tags are used, H1 shall be the first." |
| 10025 | One or more heading-level skips were detected in document order — e.g. an H1 immediately followed by an H3, skipping H2. ISO 14289-1 §7.4.2 requires descending heading sequences to proceed in strict numerical order without skipping intervening levels. |
| 10026 | One or more Widget annotations lack a /StructParent entry. ISO 14289-1 §7.18.4 requires Widget annotations to be nested within a Form structure tag; without /StructParent the Widget cannot possibly be reached from the structure tree. The detail line reports the count. |
| 10027 | One or more Widget annotations have a /StructParent entry but the value does not resolve through StructTreeRoot/ParentTree to a structure element with /S = Form. ISO 14289-1 §7.18.4 requires every Widget annotation to be nested within a Form structure tag. Possible causes: the /ParentTree entry is missing entirely, points to a non-StructElem (raw integer / MCR dict), or names a non-Form tag. |
| 10028 | One or more non-symbolic TrueType fonts have /Encoding (or an Encoding dictionary's /BaseEncoding) that is not MacRomanEncoding or WinAnsiEncoding. ISO 14289-1 §7.21.6 restricts non-symbolic TrueType encoding to these two predefined names. |
| 10029 | One or more symbolic TrueType fonts carry an /Encoding entry in the font dictionary. ISO 14289-1 §7.21.6 fourth paragraph forbids that — symbolic TrueType encoding must be expressed through the embedded font program's cmap table only. |
| 10030 | One or more L (list) structure elements lack the ListNumbering attribute. ISO 14289-1 §7.6 requires every L tag to declare its numbering style via this attribute. Valid values are None, Disc, Circle, Square, Decimal, UpperRoman, LowerRoman, UpperAlpha, and LowerAlpha (ISO 32000-1 Table 347). |
| 10031 | One or more Link annotations carry a URI action dictionary whose /IsMap entry is true. ISO 14289-1 §7.18.5 forbids /IsMap = true on a URI action unless equivalent functionality is provided elsewhere in the content without an /IsMap key. Authors with a legitimate IsMap use case should suppress this diagnostic on their own. |
| 10032 | One or more Note structure elements lack the /ID entry. ISO 14289-1 §7.9 requires every Note tag to declare a unique /ID so cross-references can land on a stable target. |
| 10033 | Two or more Note structure elements share the same /ID value. The detail line reports the number of duplicate pairs detected. ISO 14289-1 §7.9 requires Note IDs to be unique within the document. |
| 10034 | One or more non-symbolic TrueType programs (FontDescriptor with Symbolic flag cleared, FontFile2 stream present) embed a cmap table whose only subtable is the symbolic (3,0) Microsoft entry. ISO 14289-1 §7.21.6 first paragraph requires at least one non-symbolic cmap subtable so the program can render the codepoints declared by its /Encoding. |
| 10035 | One or more non-symbolic TrueType fonts declare an /Encoding with a /Differences array containing glyph names that are not members of the Adobe Glyph List 2.0. .notdef is whitelisted because the spec implicitly allows it. ISO 14289-1 §7.21.6 third paragraph requires every Differences entry to land in AGL. |
| 10042 | One or more media clip data dictionaries (identified by /S /MCD, optionally /Type /MediaClip) lack the required /CT content-type entry. ISO 14289-1 §7.18.6 promotes this ISO 32000-1 Table 274 optional key to required. |
| 10043 | One or more media clip data dictionaries lack the required /Alt array (language-string + alternate-text pairs). ISO 14289-1 §7.18.6 promotes this ISO 32000-1 Table 274 optional key to required so assistive technology can announce a description for embedded multimedia. |
| 10044 | One or more structure tree nodes carry more than one direct H (generic heading) child. ISO 14289-1 §7.4.4 explicitly forbids this — split the section, or replace the H tags with numbered H1..H6 levels. |
Remarks
The PDF/A test is intended as a fast self-check before delivery. It catches the document-level issues that disqualify a file outright (wrong PDF version, missing OutputIntent, missing structure tree at the A level, encryption, layers in PDF/A-1). It does not walk every content-stream operator nor verify font embedding or color-space references for each painted object — those validations require a dedicated PDF/A validator (such as veraPDF). Use this function as a first-line check and as a regression gate in build pipelines. Use CreatePreflightReport or SavePreflightReport when you want the library to format the issue lists into a reusable text report. Use CreatePreflightReportEx or SavePreflightReportEx for text, JSON, HTML, or CSV report output, or see Preflight Reports for the complete report workflow.
The companion API GetPDFUADiagnostics performs analogous checks for PDF/UA-1 (ISO 14289-1) on the in-memory document currently being built, rather than on an external file.
When producing PDF/A output with this library, call SetPDFAMode before adding any content. The generation-side guard inside SetPDFAMode blocks the operations forbidden by the chosen part, so a document built that way will normally pass CheckFileCompliance automatically.
Example
// Validate a delivered PDF/A file and print all issues
var
Issues, Count, I: Integer;
begin
Issues := PDF.CheckFileCompliance('archive.pdf', '', 1, 0);
if Issues = 0 then
WriteLn('archive.pdf: PDF/A conformant')
else
begin
Count := PDF.GetStringListCount(Issues);
WriteLn('archive.pdf: ', Count, ' PDF/A issue(s) detected:');
for I := 1 to Count do
WriteLn(' ', PDF.GetStringListItem(Issues, I));
end;
end;
// Fast pass/fail gate in a CI pipeline — stop on the first issue
var
Failed: Boolean;
begin
Failed := PDF.CheckFileCompliance('build/output.pdf', '', 1, 1) <> 0;
if Failed then
Halt(1);
end;See also
Preflight Reports, CreatePreflightReport, CreatePreflightReportEx, SavePreflightReport, SavePreflightReportEx, ComparePreflightReports, SetPDFAMode, GetPDFUADiagnostics, GetStringListCount, GetStringListItem, SetPDFUAMode