PDF/A Compliance for Go

Verify and convert PDF documents with a small, predictable, open source library.
The gopdfrab gopher inspecting a PDF with a magnifying glass
main.go
doc, _ := gopdfrab.Open("input.pdf")
defer doc.Close()

ok, _ := doc.IsPDFA()
if ok {
	fmt.Println("PDF/A-1b compliant")
	return
}

cr, _ := doc.Convert(gopdfrab.PDFA1B)
defer cr.Close()

cr.Save("converted.pdf")
Validation

Industry compliant

gopdfrab passes all tests in the industry supported Isartor and veraPDF test suites, and files converted by gopdfrab pass veraPDF PDF/A-1b validation.

204/204

Isartor Test Suite

569/569

veraPDF Test Suite

158

Checks across 10 groups

Features

Processing you can trust

Standards compliant, open, blazingly fast.
Full PDF/A-1b coverage
158 checks across 10 groups, green on the complete Isartor and veraPDF conformance suites and cross-checked against the veraPDF binary itself in CI.
PDF to PDF/A-1b conversion
Pre-emptive fixups, then a verify/fix loop, with a raster last resort. Anything that survives is reported as a residual, never passed off as valid.
Library and CLI
The same engine as a Go package or a single static script-friendly binary.
Object-model verification
Generic ISO 32000 checks derived from the Arlington PDF Model answer "is this even valid PDF", independent of PDF/A.
Encrypted PDFs
Standard security handler decryption — RC4 40/128, AES-128 and AES-256 — with the empty password or one you supply.
Damage recovery
Report issues in broken documents gracefully and rebuild them where possible.
Customizable profiles
Add or remove individual checks, or build a profile from scratch. Profiles are immutable and safe to share across goroutines.
Pure Go, zero runtime deps
Only the standard library. Cross-compiles anywhere Go does, including WebAssembly — this page runs it in your browser.
Open source under AGPL 3.0
Dual-licensed: AGPL 3.0 for open source, and a commercial license for closed-source use.
Benchmarks

Faster by design

A static Go binary against two JVM validators, on the same 773-file corpus.

Batch throughput

files / sec · higher is better
gopdfrab2,749
PDFBox Preflight178
veraPDF137

Whole 773-file corpus in one process. gopdfrab finishes in 0.29 s.

Cold single-file latency

ms · lower is better
gopdfrab5.4
PDFBox Preflight269
veraPDF860

One process per file, median corpus file, including process/VM startup.

Peak memory

MB · lower is better
gopdfrab67
PDFBox Preflight1,019
veraPDF736

Max RSS over the batch run.

Deployment footprint

MB · lower is better
gopdfrab3.7
PDFBox Preflight11.7
veraPDF15.3

Stripped static binary vs. CLI jars — and the jars still need a separate JRE.

Measured, not modelled: one run of the benchmark harness in the gopdfrab repo over the combined Isartor + veraPDF PDF/A-1b corpora (773 files) on a single machine, against the veraPDF greenfield CLI and PDFBox Preflight 3.0.7. Two regimes are reported and should be read together — cold runs one process per file and includes VM startup, batch runs one process for the whole corpus and isolates the engine. Startup alone is 4.1 ms for gopdfrab against 89 ms for Preflight and 613 ms for veraPDF.
API

A small, predictable API

Open, run, verify, convert.
verify.go
v, _ := doc.Verify(gopdfrab.PDFA1B)

if v.Valid {
	fmt.Println("Document is PDF/A-1b compliant")
} else {
	fmt.Println("Issues:")
	for i, issue := range v.Issues {
		fmt.Printf("#%v: %v\n", i+1, issue)
	}
}
Command line

Drops straight into CI

The same engine as a single static binary.
terminal
gopdfrab verify docs/                     # verify every PDF under a directory
gopdfrab verify --json report.pdf         # machine-readable output
gopdfrab convert in.pdf out.pdf           # rewrite towards PDF/A-1b
gopdfrab convert --dpi 300 in.pdf         # tune the raster fallback
gopdfrab verify --max-decoded-mb 64 x.pdf # cap decoded stream output at 64 MB
Robustness

Built for hostile input

The test suite covers failure modes just as heavily as successful cases, especially for untrusted and malformed PDFs.
Generated broken PDFs
An internal generator builds structurally-valid skeletons deliberately corrupted with truncation, bad xref offsets, negative stream lengths, dangling and circular references, and deep nesting.
Fuzzing at three levels
The full pipeline, isolated decoders and parsers that whole-file fuzzing only exercises lightly, and checks that look for incorrect behavior, not just crashes.
Semantic oracles
Repeat runs must match byte-for-byte, a conversion reported valid must independently re-verify as valid, and conversion must converge.
Resource limits and disclosure
Depth and size caps guard the parser, decoded-stream and cache budgets are configurable, and nothing is silently truncated.

Runs anywhere Go runs

  • Concurrency-friendly
    Verify documents in parallel across goroutines.
  • Edge-ready
    Sub-10ms cold starts make gopdfrab a fit for serverless and edge runtimes.
terminal
go get github.com/voidrab/gopdfrab

Verify your first PDF/A document

Read the docs or go straight to the source. Contributions are welcome — a bug report, a PDF that exposes an edge case, a new check, or a performance improvement all help.