{"record":{"id":"46aafbffb56e3478","repo":"hashicorp/packer","slug":"no-pem-block-found","errorCode":null,"errorMessage":"no PEM block found","messagePattern":"no PEM block found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/sign_key.go","lineNumber":176,"sourceCode":"\t}\n\n\tpublicKeyPEM, err := marshalPublicKeyPEM(signer.Public())\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tverifier, err := LoadPEMVerifierBytes(publicKeyPEM)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn signer, verifier, nil\n}\n\nfunc loadPEMPublicKey(contents []byte) (crypto.PublicKey, []byte, error) {\n\tblock, _ := pem.Decode(contents)\n\tif block == nil {\n\t\treturn nil, nil, fmt.Errorf(\"no PEM block found\")\n\t}\n\n\tif publicKey, err := x509.ParsePKIXPublicKey(block.Bytes); err == nil {\n\t\treturn publicKey, pem.EncodeToMemory(block), nil\n\t}\n\tif certificate, err := x509.ParseCertificate(block.Bytes); err == nil {\n\t\treturn certificate.PublicKey, pem.EncodeToMemory(block), nil\n\t}\n\tif privateKey, verifier, err := loadPEMPrivateKeyAsPublic(contents); err == nil {\n\t\treturn privateKey, verifier, nil\n\t}\n\n\treturn nil, nil, fmt.Errorf(\"unsupported PEM verifier data\")\n}\n\nfunc loadPEMPrivateKeyAsPublic(contents []byte) (crypto.PublicKey, []byte, error) {\n\tblock, _ := pem.Decode(contents)\n\tif block == nil {","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/sign_key.go#L158-L194","documentation":"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'.","triggerScenarios":"Calling LoadPEMVerifier or LoadPEMVerifierBytes with empty bytes, raw DER public-key bytes, plain base64, or text with a malformed PEM header.","commonSituations":"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).","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."],"exampleFix":"// before\nder, _ := os.ReadFile(\"cert.der\")\nv, err := attestation.LoadPEMVerifierBytes(der) // no PEM block found\n// after\npemBytes, _ := os.ReadFile(\"cert.pem\") // -----BEGIN CERTIFICATE-----\nv, err := attestation.LoadPEMVerifierBytes(pemBytes)","handlingStrategy":"validation","validationCode":"func hasPEM(content []byte) error {\n\tif len(bytes.TrimSpace(content)) == 0 {\n\t\treturn errors.New(\"verifier content is empty\")\n\t}\n\tif block, _ := pem.Decode(content); block == nil {\n\t\treturn errors.New(\"verifier content has no PEM armor (BEGIN/END lines missing)\")\n\t}\n\treturn nil\n}","typeGuard":"func isPEMEncoded(b []byte) bool {\n\tblock, _ := pem.Decode(b)\n\treturn block != nil\n}","tryCatchPattern":"v, err := attestation.LoadPEMVerifierBytes(content)\nif err != nil && strings.Contains(err.Error(), \"no PEM block found\") {\n\treturn fmt.Errorf(\"verifier bytes are not PEM; convert DER: openssl x509 -inform DER -pubout; first 32 bytes: %q\", content[:min(32, len(content))])\n}","preventionTips":["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."],"tags":["go","pem","encoding","attestation"],"backgroundTag":"pem-decode-failed","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}