DocuSign 'PDF_VALIDATION_FAILED' when adding documents to an envelope
Fixes DocuSign PDF_VALIDATION_FAILED when adding documents to an envelope: verify the bytes locally, strip password protection, confirm base64 integrity, and check the document entry shape. Use when generated or concatenated PDFs are rejected even though they open locally. Not for size-limit errors or rendering issues.
TL;DR
PDFVALIDATIONFAILED means the bytes you attached are not a valid, openable PDF as far as DocuSign is concerned. The usual culprits are a corrupted or truncated file, a password-protected PDF, or base64 that got mangled in transit. Verify the file opens locally, strip any password protection, confirm the base64 round-trips byte-for-byte, and resend. The envelope is rejected before creation, so nothing was sent and it is safe to retry once the bytes are clean.
The query
DocuSign 'PDF_VALIDATION_FAILED' when adding documents to an envelopeUse this when
- The create-envelope call returns errorCode PDFVALIDATIONFAILED when adding documents
- Documents generated or concatenated by your own pipeline fail but hand-made PDFs succeed
- The same file opens in Acrobat or Preview, so the failure is surprising
Not for
- Envelopes that create fine but show blank pages to signers - that is a rendering issue, not validation
- File-size limit rejections, which come back as a different error about document size
- Template-level errors that happen before any document bytes are inspected
Steps
1. Prove the file is a real PDF on your side first
Before blaming the API, check the bytes you are about to send: non-zero size, starts with the %PDF magic header, and opens in at least one reader. A zero-byte file or an HTML error page saved with a .pdf extension is the most common cause and the fastest to rule out.
import base64
raw = base64.b64decode(payload["documents"][0]["documentBase64"])
print(len(raw), raw[:5]) # expect (123456, b'%PDF-')
open("/tmp/check.pdf", "wb").write(raw)Expected output: a positive byte count and the b'%PDF-' magic; the written file opens in a PDF reader.
2. Remove password protection and encryption
DocuSign cannot validate an encrypted PDF, even if you know the password - there is no field for it on envelope creation. Decrypt the file in your pipeline before attaching it. qpdf or a PDF library can do this in one step; keep the decrypted copy only as long as the send takes.
qpdf --decrypt --password value [DOC_PASSWORD] signed.pdf clean.pdfExpected output: clean.pdf opens without a password prompt and passes the check in step 1.
3. Verify the base64 round-trips without corruption
Base64 that was URL-encoded twice, wrapped with newlines a strict decoder rejects, or truncated by a logging interceptor will fail validation. Decode what you actually send (capture the outgoing JSON, not the source file) and compare its hash to the source file's hash.
import hashlib
src = hashlib.sha256(open("contract.pdf","rb").read()).hexdigest()
sent = hashlib.sha256(base64.b64decode(sent_b64)).hexdigest()
print(src == sent)Expected output: True. If False, the corruption is in your encoding or transport layer, not in DocuSign.
4. Check the document entry itself, not just the bytes
A valid PDF still fails if the documents entry is malformed: the name must end in .pdf, each documentId must be unique within the envelope, and documentBase64 must be present and non-empty. Template-referenced documents must match the template's documentIds.
"documents": [{"documentId": "1", "name": "msa.pdf", "documentBase64": "[BASE64_BYTES]"}]Expected output: the request shape matches the API reference and every documentId is unique.
5. Retest with a known-good PDF, then bisect your generator
Send the same envelope with a small hand-made PDF. If that succeeds, the problem is in your PDF generation or concatenation step: linearized files, appended portfolios, and XFA forms are the usual suspects. Fix the generator to emit plain, unencrypted PDFs. Expected output: the known-good PDF creates the envelope, proving the failure is file-specific.
Tool compatibility
DocuSign eSignature REST API v2.1, all SDKs and direct REST calls. The validation rules are the same on demo and production. Companion tools: qpdf (decrypt and check), any PDF reader for the manual open test.
Variant phrasings
- DocuSign PDFVALIDATIONFAILED add document to envelope
- DocuSign envelope creation fails PDF validation on generated PDF
- PDFVALIDATIONFAILED errorCode DocuSign API
- DocuSign rejects PDF that opens fine in Acrobat
Why it happens
DocuSign validates document bytes before an envelope exists because a malformed document can break the signing ceremony for every recipient. The validator is stricter than desktop readers: Acrobat silently repairs a damaged trailer or prompts for a password, while the API rejects the file outright. That strictness is why a file that opens on your machine can still fail validation.
Edge cases / pitfalls
- XFA (dynamic XML) forms often fail validation - flatten them to static PDF first.
- Portfolio PDFs (multiple files in one container) are not supported as envelope documents.
- Very large documents can time out validation rather than fail it - watch for timeouts on 100+ MB files.
- A PDF/A file with embedded signatures can trip validation on some accounts; test with a plain PDF first.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_9UbPr-Hp9i6XIgCofeHIYQ