{"record":{"id":"f3feff55da52a876","repo":"hyperledger/fabric","slug":"enrollment-certificate-should-be-a-certificate-go","errorCode":null,"errorMessage":"enrollment certificate should be a certificate, got a %s instead","messagePattern":"enrollment certificate should be a certificate, got a (.+?) instead","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/common/signer/signer.go","lineNumber":87,"sourceCode":"\t}\n\tif err := validateEnrollmentCertificate(b); err != nil {\n\t\treturn nil, err\n\t}\n\tsId := &msp.SerializedIdentity{\n\t\tMspid:   mspID,\n\t\tIdBytes: b,\n\t}\n\treturn protoutil.MarshalOrPanic(sId), nil\n}\n\nfunc validateEnrollmentCertificate(b []byte) error {\n\tbl, _ := pem.Decode(b)\n\tif bl == nil {\n\t\treturn errors.Errorf(\"enrollment certificate isn't a valid PEM block\")\n\t}\n\n\tif bl.Type != \"CERTIFICATE\" {\n\t\treturn errors.Errorf(\"enrollment certificate should be a certificate, got a %s instead\", strings.ToLower(bl.Type))\n\t}\n\n\tif _, err := x509.ParseCertificate(bl.Bytes); err != nil {\n\t\treturn errors.Errorf(\"enrollment certificate is not a valid x509 certificate: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc (si *Signer) Sign(msg []byte) ([]byte, error) {\n\tswitch key := si.key.(type) {\n\t// Fabric only supports ECDSA and ed25519 at the moment.\n\tcase *ecdsa.PrivateKey:\n\t\tdigest := util.ComputeSHA256(msg)\n\t\treturn signECDSA(si.key.(*ecdsa.PrivateKey), digest)\n\tcase ed25519.PrivateKey:\n\t\treturn ed25519.Sign(si.key.(ed25519.PrivateKey), msg), nil\n\tdefault:\n\t\treturn nil, errors.Errorf(\"found unknown private key type (%T) in msg signing\", key)","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/cmd/common/signer/signer.go#L69-L105","documentation":"After successfully PEM-decoding the enrollment certificate, validateEnrollmentCertificate checks that the block type is exactly 'CERTIFICATE'. If a different PEM type (e.g. a private key, CSR, or public key) was supplied as the identity, this error reports the actual (lowercased) type found.","triggerScenarios":"Pointing signer.identity at the private key file (BEGIN PRIVATE KEY / BEGIN EC PRIVATE KEY), a CSR (BEGIN CERTIFICATE REQUEST), or a public key (BEGIN PUBLIC KEY) instead of the enrollment certificate.","commonSituations":"Swapped identity/key paths in config.yaml; concatenating key+cert and parsing picks the wrong block; using an admin's CSR instead of the issued cert; fetching the wrong file from a crypto-material directory.","solutions":["Set identity to the file containing '-----BEGIN CERTIFICATE-----' and key to the private key file","Swap the identity and key values in config if they were mixed up","Split a combined PEM file and use only the CERTIFICATE block as identity"],"exampleFix":"// before (config.yaml)\nsigner:\n  identity: /path/to/key.pem\n  key: /path/to/cert.pem\n// after\nsigner:\n  identity: /path/to/cert.pem\n  key: /path/to/key.pem","handlingStrategy":"validation","validationCode":"blk, _ := pem.Decode(b)\nif blk == nil || blk.Type != \"CERTIFICATE\" {\n    return fmt.Errorf(\"expected CERTIFICATE, got %v\", blk)\n}","typeGuard":"func isCertificateBlock(b []byte) bool {\n    blk, _ := pem.Decode(b)\n    return blk != nil && blk.Type == \"CERTIFICATE\"\n}","tryCatchPattern":"if err := validateEnrollmentCertificate(b); err != nil {\n    if strings.Contains(err.Error(), \"got a\") {\n        return fmt.Errorf(\"identity file has wrong PEM type: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep cert and key in separate, clearly named files","Don't concatenate key+cert into the identity file","Verify headers: identity must begin with BEGIN CERTIFICATE"],"tags":["pem","certificate","fabric","misconfiguration"],"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"}