{"record":{"id":"d27ecb15455649e2","repo":"hyperledger/fabric","slug":"pem-type-is-s-should-be-certificate-or-missing","errorCode":null,"errorMessage":"pem type is %s, should be 'CERTIFICATE' or missing","messagePattern":"pem type is (.+?), should be 'CERTIFICATE' or missing","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/mspimpl.go","lineNumber":965,"sourceCode":"// IsWellFormed checks if the given identity can be deserialized into its provider-specific form.\n// In this MSP implementation, well formed means that the PEM has a Type which is either\n// the string 'CERTIFICATE' or the Type is missing altogether.\nfunc (msp *bccspmsp) IsWellFormed(identity *m.SerializedIdentity) error {\n\tbl, rest := pem.Decode(identity.IdBytes)\n\tif bl == nil {\n\t\treturn errors.New(\"PEM decoding resulted in an empty block\")\n\t}\n\tif len(rest) > 0 {\n\t\treturn errors.Errorf(\"identity %s for MSP %s has trailing bytes\", string(identity.IdBytes), identity.Mspid)\n\t}\n\n\t// Important: This method looks very similar to getCertFromPem(idBytes []byte) (*x509.Certificate, error)\n\t// But we:\n\t// 1) Must ensure PEM block is of type CERTIFICATE or is empty\n\t// 2) Must not replace getCertFromPem with this method otherwise we will introduce\n\t//    a change in validation logic which will result in a chain fork.\n\tif bl.Type != \"CERTIFICATE\" && bl.Type != \"\" {\n\t\treturn errors.Errorf(\"pem type is %s, should be 'CERTIFICATE' or missing\", bl.Type)\n\t}\n\tcert, err := x509.ParseCertificate(bl.Bytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !isECDSASignedCert(cert) {\n\t\treturn nil\n\t}\n\n\treturn isIdentitySignedInCanonicalForm(cert.Signature, identity.Mspid, identity.IdBytes)\n}\n\nfunc isIdentitySignedInCanonicalForm(sig []byte, mspID string, pemEncodedIdentity []byte) error {\n\tr, s, err := utils.UnmarshalECDSASignature(sig)\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":947,"sourceCodeEnd":983,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/mspimpl.go#L947-L983","documentation":"A well-formed identity PEM must have block type CERTIFICATE (or empty, for tolerance). Any other PEM type — PRIVATE KEY, PUBLIC KEY, CSR, etc. — is rejected because the identity bytes must contain the identity's X.509 certificate. The error reports the offending type.","triggerScenarios":"IsWellFormed receives an IdBytes PEM block whose Type is e.g. 'PRIVATE KEY', 'CERTIFICATE REQUEST', 'ENCRYPTED PRIVATE KEY' — i.e. the wrong PEM file was supplied as the identity certificate.","commonSituations":"Pointing the SDK/identity loader at the keystore (private key) file instead of signcerts; submitting a CSR instead of the issued cert; env var or config mixups between key and cert paths.","solutions":["Supply the certificate PEM (-----BEGIN CERTIFICATE-----) from the MSP signcerts folder, not the key file","Verify the PEM header line before submission: it must read BEGIN CERTIFICATE","Fix path/config mix-ups between the keystore (private key) and signcerts directories","Re-run fabric-ca-client enroll and copy msp/signcerts/*.pem as the identity"],"exampleFix":"// before\n// IdBytes: -----BEGIN PRIVATE KEY-----...\n// after\n// IdBytes: -----BEGIN CERTIFICATE-----... (from msp/signcerts/cert.pem)","handlingStrategy":"validation","validationCode":"blk, _ := pem.Decode(idBytes)\nif blk == nil || (blk.Type != \"CERTIFICATE\" && blk.Type != \"\") {\n\treturn fmt.Errorf(\"expected CERTIFICATE pem, got %q\", blk.Type)\n}","typeGuard":"func isCertPEM(b []byte) bool {\n\tblk, _ := pem.Decode(b)\n\treturn blk != nil && blk.Type == \"CERTIFICATE\"\n}","tryCatchPattern":"if err := msp.IsWellFormed(si); err != nil {\n\tif strings.Contains(err.Error(), \"should be 'CERTIFICATE'\") {\n\t\t// wrong PEM type supplied: load from signcerts instead\n\t}\n\treturn err\n}","preventionTips":["Separate key and cert paths in configuration; double-check env vars","Name files clearly (cert.pem vs key.pem) to avoid mix-ups","Grep the PEM header type before loading identity material"],"tags":["pem","x509","fabric","config"],"backgroundTag":"wrong-pem-block-type","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}