DEV Community

ThomasMoore157
ThomasMoore157

Posted on

Go PDF Decrypt Wrong Password Error Explained — Supplier Invoice Handling

Short answer: quarantine a supplier's encrypted PDF when decryption reports a wrong password, preserve the original bytes, and request a corrected credential through an approved channel; do not retry the same secret across invoice jobs. For an edtech order-to-invoice pipeline, keep that attachment failure separate from rendering the invoice from trusted order data. The deciding constraint is whether the supplier attachment must appear in the final PDF: including it changes both the fidelity requirement and the amount of rendering work.

Why does supplier PDF decrypt fail with a wrong password error?

A password error tells you that the current credential did not open the document under the reader's supported PDF encryption rules. It does not prove the supplier gave the wrong password: the bytes might be truncated, a credential might have been altered in transit, or the reader might not support the document's security settings. ISO 32000-2 defines PDF as the document format; it does not promise that every tool can open every encrypted input. Treat these as hypotheses to test, not excuses to run the password through a loop.

The operational signal is a failed attachment-ingest step tied to one immutable input digest, not an invoice renderer alarm. If the order data is valid and policy permits an invoice without the attachment, generation can proceed with an explicit attachment-pending state. If policy requires the supplier document to accompany the invoice, hold delivery instead. Never imply that a missing page was rendered successfully.

That distinction matters.

One bad attachment can consume a disproportionate share of worker capacity if each invoice attempt repeats decryption and rendering. Keep a separate queue or concurrency budget for attachment inspection, and alert on the age of held orders against the delivery SLO, not just on a count of password errors. A rising queue age matters even when the error rate looks flat.

Is the input encrypted, damaged, or just mismatched?

Start with the exact bytes received. Record a cryptographic digest, byte count, ingestion timestamp, and a non-sensitive correlation ID; compare the digest on each attempt. Do not log passwords, extracted text, invoice contents, or raw PDFs. Verify that transport delivered the whole object and that the credential lookup refers to this supplier and this document version. If the digest changes, it is a different input and deserves a new inspection result.

Then have an isolated parser distinguish structural failure, encrypted input, unsupported security parameters, and authentication failure. The labels are diagnostic states, not messages to show an end user. A document that opens with a corrected credential may still fail page extraction or rendering, so treat successful authentication as a transition, not a completed invoice. Access to encrypted supplier material should be limited to the inspection worker and bounded by retention policy.

Here is the buy-versus-build question for the inspection stage, without assuming either implementation will accept a particular file:

Boundary Managed inspection Self-hosted inspection
Credential custody Check where secrets and input bytes are processed and retained Define secret delivery, memory lifetime, and deletion yourself
Unsupported encryption Confirm how the service reports unsupported inputs Pin parser capabilities and test upgrades against fixtures
Capacity Confirm concurrency limits and failure isolation Reserve worker capacity and own saturation alerts
On-call load Contract still needs clear error categories and escalation Team owns patching and incident response

Neither column resolves a wrong credential. The limitation of managed inspection is that an external processing boundary may be unsuitable for documents whose custody policy prohibits third-party access; the self-hosted trade-off is that the platform team must maintain parser isolation, security updates, and enough worker headroom. Choose the boundary whose failure classification and custody can actually be audited within your team's on-call budget.

No parser can infer the missing secret.

How should the intake boundary behave?

Keep order validation independent of the supplier PDF. The following Go sketch records a typed outcome and avoids placing a credential or document contents in logs; Inspector is an interface so its implementation can enforce parser isolation and resource limits. The digest is over the original bytes, before any attempted decryption.

package intake

import (
    "context"
    "crypto/sha256"
)

type Result string

const (
    Ready Result = "ready"
    CredentialRequired Result = "credential_required"
    Unsupported Result = "unsupported"
    InvalidPDF Result = "invalid_pdf"
)

type Inspector interface {
    Open(ctx context.Context, document []byte, credential []byte) Result
}

type IntakeResult struct {
    Digest [32]byte
    Status Result
}

func Inspect(ctx context.Context, parser Inspector, document, credential []byte) IntakeResult {
    return IntakeResult{
        Digest: sha256.Sum256(document),
        Status: parser.Open(ctx, document, credential),
    }
}
Enter fullscreen mode Exit fullscreen mode

The interface does not magically classify failures: the adapter must map its parser's documented outcomes, enforce a time and memory budget, and test that credentials do not enter traces. Avoid storing the credential alongside the job payload. For each digest and credential version, make inspection idempotent; a new version is an explicit operator or supplier action, not an automatic retry of the same input.

Invoice fidelity is a separate gate. Render from normalized order data, then verify the required amounts, page count, and attachment presence against the order's delivery policy. A PDF that opens is not necessarily an accurate invoice. If the attachment is included, account for its pages and rendering time in capacity planning; if it is merely evidence held for review, do not repeatedly rasterize it during invoice retries. Consider an order with two line items and one protected supplier attachment: validation of both item amounts should complete without any dependency on the attachment credential, while the delivery decision depends on whether that attachment is mandatory. Reprocessing the same attachment after each amount check adds load without improving either the invoice or the credential.

What proves recovery, and how do we roll back?

Build test fixtures for an open PDF, an encrypted PDF with the wrong credential, the same file with the right credential, a truncated input, and a file the selected parser cannot support. Assert that an unchanged digest and credential version do not trigger repeated inspection. Test both delivery policies: an invoice allowed without a pending attachment and an invoice that must be held. Verify that output amounts remain tied to order data rather than extracted attachment text.

During deployment, measure inspection queue age, per-outcome counts, worker saturation, and invoice delivery latency. Keep labels low-cardinality: supplier ID or document digest belongs in restricted diagnostic records, not broad metrics. Reconcile a sample of rendered invoices against their normalized orders before expanding concurrency.

If the new intake path misclassifies documents, stop dispatching new inspections to it and route new inputs to the last validated path; keep existing held documents and their original bytes intact for reinspection. Do not turn off the attachment requirement to clear the queue. Recovery is complete only when the corrected document passes inspection, the invoice passes its independent fidelity checks, and the delivery state matches policy.

References

Top comments (0)