Skip to main content

Sigstore / cosign · troubleshooting

Error: no matching signatures

cosign found no signature on the image that satisfies the identity you asked it to accept. Either nothing signed it, or something did and you are checking for a different signer — and the message is the same either way.

Run this first

step 1 of 3
cosign verify <image> --certificate-identity-regexp '.*' --certificate-oidc-issuer-regexp '.*'

Look for Success, and the certificate subject and issuer it prints

Separates the two situations the error conflates. Succeeding means a signature exists and your identity match was wrong; failing means there is nothing there to match.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Does cosign verify succeed when you match the identity and issuer with '.*' regexps?

This asks only 'is there any signature at all', separating a missing signature from a mismatched identity.

Cause space

5 of 5 still possible

  • The identity or issuer you are matching is not the one that signedCommon
  • Nothing signed this imageCommon
  • The command omits the identity flags entirelyOccasional
  • You are verifying a different image than you thinkOccasional
  • The transparency log cannot be reached or consultedRare

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Check it with a tool

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    cosign verify <image> --certificate-identity-regexp '.*' --certificate-oidc-issuer-regexp '.*'

    Separates the two situations the error conflates. Succeeding means a signature exists and your identity match was wrong; failing means there is nothing there to match.

    Look for Success, and the certificate subject and issuer it prints

  2. Step 2

    cosign triangulate <image>

    Names the exact registry reference a signature would live at, so 'is it signed' becomes a question you can answer by looking.

    Look for A reference the registry actually holds

  3. Step 3

    crane digest <image>:<tag>

    Confirms the tag still resolves to the digest that was signed. A rebuilt tag is the quiet version of this failure.

    Look for A digest matching the one the signing job reported

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

The identity or issuer you are matching is not the one that signed

Common

The signature exists and is valid; it simply was not made by the identity in your flags. A workflow moved to a different repository or ref, the signing job was renamed, or the issuer is written as one of the several forms a provider can present. cosign compares these as strings, so near enough is not enough.

Confirm

cosign verify <image> --certificate-identity-regexp '.*' --certificate-oidc-issuer-regexp '.*'

Whether verification now succeeds. If it does, a signature exists and the identity you were matching is the thing that was wrong

Fix

  • Read the identity out of the signature rather than constructing it: the regexp form above prints the certificate subject that actually signed.
  • Match that exact value, or a regexp deliberately anchored to it — not a wildcard left in place after debugging.
  • If signing moved between repositories or refs, the identity changed with it and the verification side has to change too.
cosign verify <image> --certificate-identity '<exact subject from above>' --certificate-oidc-issuer '<exact issuer>'

Nothing signed this image

Common

The signing step never ran, ran on a different tag, or ran on a digest that a later rebuild replaced. Because signatures attach to a digest, re-pushing the same tag from a new build leaves the old signature pointing at an image nobody is pulling any more — so the tag looks signed in the registry's history and verifies as unsigned today.

Confirm

cosign triangulate <image>

The signature tag cosign expects. If the registry has nothing at that reference, the image genuinely carries no signature

Fix

  • Confirm the signing step ran in the build that produced the digest you are verifying, not merely in some earlier build of the same tag.
  • Sign by digest and verify by digest wherever the pipeline allows it; a mutable tag makes this failure recurrent and confusing.
  • Check the signing step's own exit status — a signature step that failed quietly leaves exactly this state.

The command omits the identity flags entirely

Occasional

Keyless verification needs both --certificate-identity and --certificate-oidc-issuer. A command carrying neither is either refused or is not performing the check its author intended. This is most often inherited: a snippet written for cosign 1.x, or copied from a key-based example where the flags do not apply.

Confirm

history | grep 'cosign verify' | tail -5

A verify command with neither --certificate-identity nor --key — which cannot express what it is meant to accept

Fix

  • Add both flags. Sigstore documents them as the shape of a keyless verification.
  • If the image is signed with a key rather than keylessly, use --key instead; the two modes are not interchangeable.

You are verifying a different image than you think

Occasional

A tag resolved at verification time can differ from the one signed minutes earlier — a parallel build, a mirror that lags, or a multi-arch index where the signature sits on one manifest and the pull resolves to another. The verification is honest; the reference is ambiguous.

Confirm

crane digest <image>:<tag>

Whether this digest matches the one the signing job recorded in its output

Fix

  • Pin to a digest end to end: sign the digest, promote the digest, verify the digest.
  • For multi-arch images, confirm whether your policy expects the index or the per-platform manifest to carry the signature.

The transparency log cannot be reached or consulted

Rare

Keyless verification normally checks the signature was recorded in a public transparency log. In an air-gapped or egress-restricted environment that lookup fails, and the outcome is a refusal rather than a network error. Distinguished by affecting every image at once, including ones known to be signed.

Confirm

cosign verify <image> --certificate-identity '<id>' --certificate-oidc-issuer '<issuer>' --verbose

Mentions of Rekor, the transparency log, or a timeout reaching it, rather than an identity mismatch

Fix

  • Give the verifying host egress to the transparency log, or run and point at your own instance.
  • Treat any flag that skips the log as a change in what you are asserting, not as a workaround — record why it was needed.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

What is actually happening

Verification is not a yes/no question about whether an image is signed. It asks a narrower one: is there a signature on this image, made by *this identity*, issued by *this OIDC provider*. "No matching signatures" is the answer no to that whole question, and it does not say which part failed.

That ambiguity is the reason this page exists. Two very different situations produce identical output: an image nobody signed, and an image signed correctly by a pipeline whose identity you spelled differently. The first is a supply-chain finding. The second is a typo. Treating them the same way is how verification ends up switched off.

Sigstore's documentation is explicit that keyless verification takes both `--certificate-identity` and `--certificate-oidc-issuer`. They are not optional hardening — without them cosign has no identity to match against, and a command that omits them is not doing the check you think it is.

Cosign 2.0 tightened this deliberately. If a command that worked on an older cosign now fails, the binary changed under you rather than the image.

How to tell this is your problem
WhereWhat you see
cosign verify"Error: no matching signatures", usually with a non-zero exit
A CI gateThe verify step failing while the build and push steps succeeded
Kubernetes admissionA policy controller rejecting the pod, with the image named but no signer detail

How to know it is actually fixed

  • cosign verify succeeds with the real identity and issuer in place — not with a regexp wildcard left over from debugging.
  • The same command run against a deliberately unsigned image still fails. A check that passes everything is not a check.
  • If a policy controller enforces this, deploy an unsigned image to a scratch namespace and confirm it is refused.

Stopping it happening again

  • Sign and verify by digest. Tags are mutable and this is the failure mode that mutability produces.
  • Keep the verifying identity next to the signing identity in the same repository, so a change to one is visible in the diff of the other.
  • Fail the pipeline when signing fails. An unsigned image that ships is worse than a build that stops.
  • Never resolve a verification failure by removing the verification. Record what was wrong, then restore the check.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Related