hashicorp/packer · error
no PEM block found
Error message
no PEM block found
What it means
loadPEMPublicKey (used by LoadPEMVerifier and LoadPEMVerifierBytes) found no PEM block: pem.Decode returned nil because the byte slice lacks valid '-----BEGIN/END-----' armor. This is the inner error normally surfaced to callers wrapped as 'load verifier %q: %w'.
Source
Thrown at internal/attestation/sign_key.go:176
}
publicKeyPEM, err := marshalPublicKeyPEM(signer.Public())
if err != nil {
return nil, nil, err
}
verifier, err := LoadPEMVerifierBytes(publicKeyPEM)
if err != nil {
return nil, nil, err
}
return signer, verifier, nil
}
func loadPEMPublicKey(contents []byte) (crypto.PublicKey, []byte, error) {
block, _ := pem.Decode(contents)
if block == nil {
return nil, nil, fmt.Errorf("no PEM block found")
}
if publicKey, err := x509.ParsePKIXPublicKey(block.Bytes); err == nil {
return publicKey, pem.EncodeToMemory(block), nil
}
if certificate, err := x509.ParseCertificate(block.Bytes); err == nil {
return certificate.PublicKey, pem.EncodeToMemory(block), nil
}
if privateKey, verifier, err := loadPEMPrivateKeyAsPublic(contents); err == nil {
return privateKey, verifier, nil
}
return nil, nil, fmt.Errorf("unsupported PEM verifier data")
}
func loadPEMPrivateKeyAsPublic(contents []byte) (crypto.PublicKey, []byte, error) {
block, _ := pem.Decode(contents)
if block == nil {View on GitHub (pinned to eb36e3c3e4)
Solutions
- Ensure the content includes PEM armor ('-----BEGIN PUBLIC KEY-----' or '-----BEGIN CERTIFICATE-----').
- Convert DER to PEM: 'openssl x509 -inform DER -in cert.der -out cert.pem' or 'openssl pkey -pubin -inform DER -pubout'.
- If content is fetched at runtime, log its first line to confirm armor is present before calling the loader.
- Prefer LoadPEMVerifierBytes in tests with known-good PEM to isolate format from path issues.
Example fix
// before
der, _ := os.ReadFile("cert.der")
v, err := attestation.LoadPEMVerifierBytes(der) // no PEM block found
// after
pemBytes, _ := os.ReadFile("cert.pem") // -----BEGIN CERTIFICATE-----
v, err := attestation.LoadPEMVerifierBytes(pemBytes) Defensive patterns
Strategy: validation
Validate before calling
func hasPEM(content []byte) error {
if len(bytes.TrimSpace(content)) == 0 {
return errors.New("verifier content is empty")
}
if block, _ := pem.Decode(content); block == nil {
return errors.New("verifier content has no PEM armor (BEGIN/END lines missing)")
}
return nil
} Type guard
func isPEMEncoded(b []byte) bool {
block, _ := pem.Decode(b)
return block != nil
} Try / catch
v, err := attestation.LoadPEMVerifierBytes(content)
if err != nil && strings.Contains(err.Error(), "no PEM block found") {
return fmt.Errorf("verifier bytes are not PEM; convert DER: openssl x509 -inform DER -pubout; first 32 bytes: %q", content[:min(32, len(content))])
} Prevention
- Log or inspect the first line of key material when debugging: it must read '-----BEGIN ...'.
- Store and transfer keys only in PEM form; convert DER at the edge.
- Guard against empty files (failed writes) before loading.
- Cover loader calls in tests with both PEM and DER fixtures to catch format regressions.
When it happens
Trigger: Calling LoadPEMVerifier or LoadPEMVerifierBytes with empty bytes, raw DER public-key bytes, plain base64, or text with a malformed PEM header.
Common situations: Embedding a raw DER certificate in config; a fetch script that wrote binary content; copy-paste losing the BEGIN/END lines; reading the wrong file (e.g. a checksum or signature file).
Related errors
- read verifier %q: %w
- load verifier %q: %w
- decode signer %q: no PEM block found
- decode keyless certificate: no PEM block found
- parse keyless certificate: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/46aafbffb56e3478.
Report an issue: GitHub.