hashicorp/packer · error
keyless attestation does not contain a signing certificate
Error message
keyless attestation does not contain a signing certificate
What it means
certificateFromEnvelope examined every signature in the envelope and found none with a non-empty Cert field. Keyless attestations must carry the Fulcio-issued signing certificate in the signature so the verifier can establish identity; an envelope without one cannot be verified in keyless mode.
Source
Thrown at internal/attestation/sign_keyless.go:287
for _, signature := range envelope.Signatures {
if strings.TrimSpace(signature.Cert) == "" {
continue
}
block, _ := pem.Decode([]byte(signature.Cert))
if block == nil {
return nil, fmt.Errorf("decode keyless certificate: no PEM block found")
}
certificate, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, fmt.Errorf("parse keyless certificate: %w", err)
}
return certificate, nil
}
return nil, fmt.Errorf("keyless attestation does not contain a signing certificate")
}
type staticCertificateProvider struct {
certDER []byte
}
func (p staticCertificateProvider) GetCertificate(context.Context, sigstoregosign.Keypair, *sigstoregosign.CertificateProviderOptions) ([]byte, error) {
if len(p.certDER) == 0 {
return nil, fmt.Errorf("static certificate provider is missing a certificate")
}
return append([]byte(nil), p.certDER...), nil
}
func resolveAmbientIDToken(ctx context.Context, env map[string]string) (string, error) {
if token := strings.TrimSpace(env["SIGSTORE_ID_TOKEN"]); token != "" {
return token, nil
}View on GitHub (pinned to eb36e3c3e4)
Solutions
- Verify the attestation was produced with signing_mode="keyless"; if it was key-backed, use the corresponding key-based verifier.
- Check that the producer populated EnvelopeSignature.Cert with the PEM certificate (as keylessSigner.SignBundle does).
- Re-sign/re-attest the payload if the source envelope is missing the certificate by design.
- Log the number of signatures and their Cert lengths before calling to confirm the envelope shape.
Example fix
// before
v, err := newKeylessVerifierForEnvelope(cfg, envelope)
// after
hasCert := false
for _, s := range envelope.Signatures {
if strings.TrimSpace(s.Cert) != "" {
hasCert = true
}
}
if !hasCert {
return fmt.Errorf("envelope has no signing certificate; use the key-based verifier")
}
v, err := newKeylessVerifierForEnvelope(cfg, envelope) Defensive patterns
Strategy: validation
Validate before calling
func envelopeHasCertificate(env Envelope) bool {
for _, s := range env.Signatures {
if strings.TrimSpace(s.Cert) != "" {
return true
}
}
return false
}
if !envelopeHasCertificate(envelope) {
return fmt.Errorf("envelope carries no signing certificate; use a key-based verifier")
} Type guard
func isKeylessEnvelope(env Envelope) bool {
return envelopeHasCertificate(env)
} Try / catch
verifier, err := newKeylessVerifierForEnvelope(cfg, envelope)
if err != nil && strings.Contains(err.Error(), "does not contain a signing certificate") {
// fall back to the key-based verifier for non-keyless attestations
verifier, err = newKeyVerifier(cfg, envelope)
} Prevention
- Match the verifier mode to the producer's signing_mode before verification.
- Require Cert to be populated in keyless attestation schemas.
- Route key-backed and keyless attestations through different verification paths.
- Record the signing mode alongside stored attestations.
When it happens
Trigger: newKeylessVerifierForEnvelope is called with an Envelope produced by a key-backed signer (signing_mode other than "keyless") or an envelope whose signatures all have empty/whitespace-only Cert fields.
Common situations: Mixing signing modes: verifying a key-signed or none-mode attestation with keyless verification config; an external tool produced a Sigstore bundle stripped of its certificate; deserialization dropped the Cert field.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- signing_mode %q does not support Sigstore bundle emission
- decode envelope payload: %w
- decode envelope signature: %w
- read verifier %q: %w
- load verifier %q: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/28043e677d9463bf.
Report an issue: GitHub.