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")
Try it

Validate or convert directly in your browser

Files never leave your device as gopdfrab runs locally as WebAssembly.
PDF/A validator
Check a PDF against ISO 19005-1.
PDF to PDF/A converter
Drop a PDF in and get a PDF/A-1b document back.
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

159

gopdfrab checks, in 11 groups

Features

Processing you can trust

Standards compliant, open, blazingly fast.
Full PDF/A-1b coverage
A PDF/A-1b profile of 159 checks across 11 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,939
PDFBox Preflight155
veraPDF130

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

Cold single-file latency

ms · lower is better
gopdfrab9.5
PDFBox Preflight295
veraPDF991

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

Peak memory

MB · lower is better
gopdfrab80
PDFBox Preflight945
veraPDF728

Max RSS over the batch run.

Deployment footprint

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

Stripped static binary vs. CLI jars. The binary sizes are close — the difference is that the jars additionally need a JRE, another 40 to 200 MB, and the gopdfrab binary contains fonts and colorspaces for the PDF/A conversion functionality.

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.

Runs anywhere Go runs

  • Concurrency-friendly
    Verify documents in parallel across goroutines.
  • Edge-ready
    Cold starts of about 9.5 ms 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.