Adobe Says "At Least One Signature Has Problems" — How to Find Out Which, and Why
Open a signed PDF in Adobe Acrobat Reader and you may get a blue-grey bar across the top: "At least one signature has problems." That is not a diagnosis. It is a summary of a summary — Adobe has run its checks, at least one of them came back unhappy, and it is declining to say which on the document bar.
The message is worth understanding precisely, because two different mistakes are common. One is panicking: the underlying cause is usually a trust configuration issue, not a forged document. The other is dismissing it: sometimes it really does mean the file was modified. The banner cannot tell you which, and it is not trying to.
This post explains the wording, lists everything that can produce it, and shows how to get the actual failing check instead of the banner.
Why "at least one"
The phrasing is not hedging. It is literal, and it points at something people miss: a PDF can carry any number of signatures, and Adobe's document bar reports the worst verdict among them, not a verdict on the document.
A countersigned contract with three signatures can have two perfect signatures and one from a signer whose certificate you do not trust. The document bar says "at least one signature has problems." Nothing on that bar tells you it was the third one, or that the other two are fine. On a single-signature document the wording is just noise; on a multi-signature document it is the whole story, and it is the reason you have to open the Signature Panel rather than act on the bar.
If you build software that verifies PDFs, this is the first thing to get right: verdicts belong per signature, not per document. Collapsing them the way the banner does throws away the information the user actually needs.
Where the real reason lives
In Acrobat, the banner has a Signature Panel button on its right. Open it, expand the signature, and expand "Signature Details" → "Certificate Details." That is where the specific complaint is written. The banner is a routing device; the panel is the answer.
Broadly, what you find there falls into two families, and they mean opposite things:
- A trust problem. The cryptography is perfect. Adobe cannot establish who signed, because the signer's certificate does not chain to a root it trusts. Adobe words this as "signature validity is UNKNOWN," and it is by a wide margin the most common cause of the banner. The document is intact. See Why Adobe Says "Signature Validity Is Unknown".
- An integrity problem. The bytes covered by the signature are not the bytes in front of the reader. Adobe words this as "the document has been altered or corrupted since it was signed." Sometimes that means tampering; more often it means the file legitimately grew after signing. See Why Adobe Says "Altered or Corrupted".
Those two cover most cases. They do not cover all of them, and the remainder is where people get stuck, because the sibling explanations do not apply and the panel text is terse.
The other five reasons
Verification is not one test. VerifyKit models it as eight independent checks, which is roughly the same decomposition Acrobat performs internally, and any one of them can be what put the banner on your screen.
Beyond integrity and trust, these five are the ones that produce a problem banner on a document nobody touched:
The signer's certificate had expired. The correct question is not "has this certificate expired?" — it is "was it valid at the time of signing?" A signature made in 2023 with a certificate that expired in 2024 is still a good signature; certificates expire, signatures do not. VerifyKit's expiryCheck evaluates validity at signing time for exactly this reason. But that only works if the signing time can be trusted, which brings us to the next one.
There is no trusted timestamp. The /M entry in a signature dictionary is just a claimed date — written by the signer's own software, unauthenticated, trivially set to anything. A real RFC 3161 timestamp from a Time Stamping Authority is a separate signature over your signature, proving the document existed in that form by that moment. Without one, a verifier has no trustworthy signing time, so it has to fall back on evaluating the certificate against now — and then a long-expired certificate does drag the verdict down. This is the single most common reason an old, perfectly legitimate document degrades over time. timestampCheck reports whether one is present and valid; sig.timestamp carries the TSA name and time when it is.
The certificate was revoked. A certificate can be cancelled before its expiry date — the key was compromised, or the holder left the organisation. Revocation is published via CRL or OCSP, and checking it requires a network request, so it is not always performed. VerifyKit puts online revocation behind a plugin and marks revocationCheck.attempted accordingly, which lets you distinguish "not checked" from "checked and inconclusive" from "checked and revoked." Those three deserve three different messages to a user, and most viewers give them one.
A weak algorithm was used. A signature made with SHA-1 or MD5 is cryptographically obsolete regardless of whether the math verifies, and modern policy rejects it. algorithmCheck reports this, and populates algorithmName with the resolved name — so you can show "Signed with SHA-1" as a badge even when the check itself fails. Old documents from long-lived archives hit this constantly.
The certificate lacks the right Extended Key Usage. An X.509 certificate states what its key may be used for. For document signing, it should carry id-kp-documentSigning or id-kp-emailProtection. A certificate issued for TLS server authentication and pressed into service for signing PDFs is being used outside its stated purpose, and ekuCheck says so.
Getting the actual failing check
The reason to reach for an SDK rather than a screenshot of a banner is that all eight results are just fields you can read. Each is a SignatureCheckResult with a label, a status, and a detail explaining the outcome in words:
import { createVerifier } from '@trexolab/verifykit-core'
const verifier = await createVerifier()
const result = await verifier.verify(buffer, 'contract.pdf')
result.signatures.forEach((sig, i) => {
console.log(`Signature ${i + 1}: ${sig.name} — ${sig.overallStatus}`)
const checks = [
sig.integrityCheck,
sig.signatureCheck,
sig.certificateChainCheck,
sig.expiryCheck,
sig.timestampCheck,
sig.revocationCheck,
sig.algorithmCheck,
sig.ekuCheck,
]
for (const check of checks) {
if (check.status !== 'valid') {
console.log(` ${check.label}: ${check.status} — ${check.detail}`)
}
}
})
verifier.dispose()That loop is the whole of what the banner refuses to tell you: which signature, which check, and why. Every check reports independently, so a signature that is cryptographically flawless but untrusted comes back with seven valid results and one that is not — and you can say so, instead of showing a document-level warning that implies everything is suspect.
A note on statuses: there are five, not two. valid, invalid, warning, unknown, and pending. The one that matters most is the difference between invalid and unknown. invalid means something is actually wrong — the content changed, the math failed, the certificate was revoked. unknown means the verifier could not establish trust or could not reach a service. Collapsing unknown into invalid is how you end up telling a user their valid contract is forged; collapsing it into valid is how you end up showing a green tick for a self-signed document from anybody at all.
Triage in order
If you just want to get to the bottom of a specific file, work down this list:
- How many signatures does the document have? If more than one, find out which is unhappy before anything else. The banner is about the worst of them.
- Is it a trust problem? Look for "unknown" wording, or a
certificateChainCheckthat fails whileintegrityCheckandsignatureCheckpass. This is the common case and it is fixed by adding the right root certificate, not by touching the document. - Is it an integrity problem?
integrityCheckfailing means the bytes changed. Check whether the file passed through anything that rewrites PDFs after signing. - Is the certificate expired, and is there a timestamp? An expired certificate plus a valid timestamp is fine. An expired certificate with no timestamp is a document that has quietly aged out, and no configuration change will restore it.
- Everything else — revocation, algorithm, EKU. Rarer, and each has a specific, readable
detailstring.
The fastest way to run all five at once is to put the file through a verifier that reports the checks separately. The live demo does exactly that, in your browser, without uploading the document anywhere.
The takeaway
"At least one signature has problems" is a banner, not a finding. It says a check somewhere failed on a signature somewhere, and it is deliberately vague because the underlying causes range from "you have not installed a root certificate" to "this file was modified after signing" — and those need completely different responses.
The fix, whether you are debugging one document or building a viewer other people rely on, is the same: stop consuming the summary and start reading the individual checks. Per signature, per check, with the reason attached.
For the full model, see Core Concepts; for every field named above, the Core API reference; and for the messages themselves, the Error Reference and Troubleshooting guide.
Need PDF signature verification in production?
VerifyKit is a commercial SDK — try the live demo, then get in touch for a license.