hashicorp/packer · error
parse keyless certificate: %w
Error message
parse keyless certificate: %w
What it means
A PEM block was successfully decoded from the signature's Cert field, but x509.ParseCertificate rejected the DER bytes inside it. This means the PEM armor is present but its payload is not a parseable X.509 certificate (wrong block type, truncated bytes, or corrupted content).
Source
Thrown at internal/attestation/sign_keyless.go:281
func (v *keylessVerifier) KeyID() string {
return v.signatureVerifier.KeyID()
}
func certificateFromEnvelope(envelope Envelope) (*x509.Certificate, error) {
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...), nilView on GitHub (pinned to eb36e3c3e4)
Solutions
- Check the wrapped x509 error for the specific ASN.1 failure (truncated, wrong type).
- Confirm the PEM block type is "CERTIFICATE" and the DER is complete (no missing final lines).
- Regenerate the attestation envelope from the original keyless signer.
- Validate the certificate with openssl x509 -in cert.pem -text -noout outside the library to isolate corruption.
Example fix
// before
block, _ := pem.Decode([]byte(sig.Cert))
cert, err := x509.ParseCertificate(block.Bytes) // fails on non-CERTIFICATE blocks
// after
block, _ := pem.Decode([]byte(sig.Cert))
if block == nil || block.Type != "CERTIFICATE" {
return fmt.Errorf("expected CERTIFICATE PEM block, got %q", blockName(block))
}
cert, err := x509.ParseCertificate(block.Bytes) Defensive patterns
Strategy: validation
Validate before calling
func validCertPEM(s string) (*x509.Certificate, error) {
block, _ := pem.Decode([]byte(s))
if block == nil || block.Type != "CERTIFICATE" {
return nil, fmt.Errorf("not a CERTIFICATE PEM block")
}
return x509.ParseCertificate(block.Bytes)
}
// pre-validate
if _, err := validCertPEM(sig.Cert); err != nil {
return fmt.Errorf("attestation certificate malformed: %w", err)
} Type guard
func parsesAsCertificate(s string) bool {
block, _ := pem.Decode([]byte(s))
if block == nil || block.Type != "CERTIFICATE" {
return false
}
_, err := x509.ParseCertificate(block.Bytes)
return err == nil
} Try / catch
verifier, err := newKeylessVerifierForEnvelope(cfg, envelope)
if err != nil && strings.Contains(err.Error(), "parse keyless certificate") {
return fmt.Errorf("attestation certificate DER is corrupt or wrong type: %w", err)
} Prevention
- Verify certificate PEMs with openssl x509 before storing attestations.
- Guard against truncation: checksum attestations in storage.
- Only accept PEM blocks of type CERTIFICATE for the Cert field.
- Keep envelopes machine-generated; avoid manual copy/paste edits.
When it happens
Trigger: certificateFromEnvelope is called (via newKeylessVerifierForEnvelope or the TestKeylessBundleAndRekorIntegration test) with an envelope whose signature Cert decodes to PEM containing non-certificate DER, truncated DER, or a private key/CSR block.
Common situations: PEM block type mismatch (e.g. CERTIFICATE REQUEST or PRIVATE KEY instead of CERTIFICATE); copy/paste truncation of the final base64 lines; corruption during storage or transmission of the attestation JSON.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- load verifier %q: %w
- decode keyless certificate: no PEM block found
- read verifier %q: %w
- no PEM block found
- unsupported PEM verifier data
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/6cdf39b9a2af2436.
Report an issue: GitHub.