What PDF/A-1b actually requires
"PDF/A-1b conformant" is one boolean. gopdfrab answers it with a set of checks organised into groups, covering ISO 19005-1 clauses 6.1 through 6.9 plus generic ISO 32000 object-model conformance. Other implementations slice the same clauses differently. Here is what each of these groups is actually asking.
The groups
File structure
Checks.Structure6.1.x — file header, trailer, xref, object framing, limits
Common failures: Encrypted document, Embedded files, LZW compression, Broken cross-reference table
Colour
Checks.Colour6.2.2 OutputIntent, 6.2.3.x device colours, 6.2.9–10
Common failures: Missing OutputIntent, Device colour without OutputIntent
Images and XObjects
Checks.Image6.2.4-6.2.7 image/form/PostScript XObjects
Transparency
Checks.Transparency6.2.8 transfer functions, 6.4 soft masks/blend modes/alpha
Common failures: Transparency in PDF/A-1, Transfer function present
Fonts
Checks.Font6.3.x embedding, subsets, metrics, encoding
Common failures: Font not embedded, Glyph not in font
Annotations
Checks.Annotation6.5.x annotation types and dictionaries
Common failures: Missing appearance stream
Actions
Checks.Action6.6.x action types and additional actions
Common failures: JavaScript or launch action
Metadata
Checks.Metadata6.7.x XMP metadata, extension schemas, PDF/A identifier
Common failures: XMP / Info mismatch
Logical structure
Checks.LogicalStructure6.8 tagged PDF structure hierarchy and marked content
Interactive forms
Checks.Form6.9 interactive forms
Object model
Checks.ObjectModelGeneric ISO 32000 object-model conformance, independent of PDF/A
One idea, restated in every group
Read the groups together and the same requirement keeps reappearing. Nothing may depend on the environment. A font by name depends on the machine. Device colour depends on the output device. Encryption depends on a key. JavaScript depends on an engine. An annotation without an appearance stream depends on the viewer's taste.
One group is not PDF/A at all
Checks.ObjectModel asks a different question. Is this even valid PDF? The checks behind it are derived from the Arlington PDF Model , and they are separable on purpose. A file can be flawless PDF that fails PDF/A, and it can carry a PDF/A identifier while containing a dictionary ISO 32000 does not permit.
Where the standard is ambiguous
Not every clause has one reading. Where ISO 19005-1 admits two, the Isartor suite encodes the strict one and veraPDF, as the reference implementation, settled on a more lenient one. gopdfrab's default PDFA1B profile follows veraPDF, and Legacy1B is the spec-literal reading.
// Verify against the legacy Isartor-derived profile instead of the
// veraPDF-aligned default
v, err := doc.Verify(gopdfrab.Legacy1B)Checks are data, not a fixed list
The registry is queryable, and a profile is a set you can add to or subtract from. That is useful when you want structural checks without the archival ones, or when one clause is genuinely not your problem.
// Start from the full profile and remove checks
p := gopdfrab.PDFA1B.
RemoveCheck(gopdfrab.Checks.Structure.FileHeaderSignature).
RemoveCheck(gopdfrab.Checks.Font.SimpleNotEmbedded)
res, err := doc.Verify(p)
// Or start from an empty profile and add only what you need
p2 := gopdfrab.PDFA1B.Clear().
AddCheck(
gopdfrab.Checks.Transparency.ImageWithSoftMask,
gopdfrab.Checks.Metadata.PDFAIdentifierMissing,
)
res2, err := doc.Verify(p2)It is worth resisting the temptation to use this on a failing document. Simply removing the failed check does not make the document conformant. It just makes your validator quiet. The error reference exists to make the other route easier.