qpdf --decrypt: Remove PDF Passwords in CI
qpdf --decrypt --password=PW in.pdf out.pdf writes a copy of an encrypted PDF with the encryption removed.
When a downstream tool cannot open a password-protected or owner-encrypted PDF, qpdf --decrypt produces an unencrypted copy. Its meaningful exit codes need handling in CI.
What it does
qpdf reads the input PDF (supplying --password if needed) and writes an output with encryption removed. It works for both user-password (open) and owner-password (permissions) encryption when you provide the correct password.
Common usage
# remove encryption using the known password
qpdf --decrypt --password=secret in.pdf out.pdf
# owner-encrypted (no open password): empty password
qpdf --decrypt in.pdf out.pdf
# check whether a PDF is encrypted
qpdf --show-encryption in.pdfOptions
| Flag | What it does |
|---|---|
| --decrypt | Write the output without encryption |
| --password=<pw> | Password to open/decrypt the input |
| --show-encryption | Report the encryption settings |
| --require-outfile=n | Allow operations without an output file |
| --replace-input | Edit the input file in place |
| --verbose | Print more detail |
In CI
qpdf uses meaningful exit codes: 0 success, 2 errors, 3 warnings (output still produced). A set -e step treats the warning code 3 as failure even though the PDF is fine, so test for -eq 2 or use --warning-exit-0. Never hardcode the password in the workflow file; pass it from a secret.
Common errors in CI
"qpdf: command not found" means install qpdf. "invalid password" means the supplied --password is wrong or the PDF needs a user password you did not provide. Exit code 3 ("operation succeeded with warnings") on a slightly malformed PDF is recoverable, not a failure; add --warning-exit-0. "input file and output file are the same" means use --replace-input instead of naming the same path twice.