{"record":{"id":"b61e886f7bb47c51","repo":"hyperledger/fabric","slug":"failed-to-traverse-certificate-verification-chain","errorCode":null,"errorMessage":"failed to traverse certificate verification chain for leaf or intermediate certificate, with subject %s","messagePattern":"failed to traverse certificate verification chain for leaf or intermediate certificate, with subject (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/mspimpl.go","lineNumber":936,"sourceCode":"\t\t// we will validate already sanitized cert\n\t\tchain, err := msp.getUniqueValidationChain(cert, validityOpts)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// once we finish validation and this is already\n\t\t// sanitized certificate, there is no need to\n\t\t// sanitize it once again hence we can just return it\n\t\tif isRootCACert {\n\t\t\treturn cert, nil\n\t\t}\n\n\t\t// ok, this is no a root CA cert, and now we\n\t\t// have chain of certs and can extract parent\n\t\t// to sanitize the cert whenever it's intermediate or leaf certificate\n\t\tvar parentCert *x509.Certificate\n\t\tif len(chain) <= 1 {\n\t\t\treturn nil, fmt.Errorf(\"failed to traverse certificate verification chain\"+\n\t\t\t\t\" for leaf or intermediate certificate, with subject %s\", cert.Subject)\n\t\t}\n\t\tparentCert = chain[1]\n\n\t\t// Sanitize\n\t\treturn sanitizeECDSASignedCert(cert, parentCert)\n\t}\n\treturn cert, nil\n}\n\n// 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}","sourceCodeStart":918,"sourceCodeEnd":954,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/mspimpl.go#L918-L954","documentation":"sanitizeCert normalizes ECDSA certificates; for a leaf or intermediate cert it must find the parent by traversing the verification chain to sanitize the signature encoding. If cert.Verify returns a chain with only the certificate itself (len <= 1), there is no parent to use and the library throws this error including the cert subject.","triggerScenarios":"newIdentity or getCertifiersIdentifier calls sanitizeCert on a non-root certificate whose Verify against the MSP options yields a single-element chain — e.g. a self-signed leaf that is also in the root pool, or verify options lacking the issuer cert.","commonSituations":"Self-signed client certificates imported into an MSP without their issuer; identity certs whose issuer is missing from cacerts/intermediatescerts; crypto material hand-assembled without a full chain.","solutions":["Add the issuing CA certificate (root or intermediate) to the MSP cacerts/intermediatescerts so a chain with a parent can be built","Use a properly enrolled identity from the fabric CA instead of self-signed certs","Verify with openssl verify -CAfile cacerts.pem cert.pem that a chain of length >=2 exists","Regenerate the crypto material with cryptogen to guarantee complete chains"],"exampleFix":"// before\n// msp/cacerts: empty; identity self-signed\n// after\n// msp/cacerts: rootCA.pem; identity issued by intermediate in intermediatescerts","handlingStrategy":"validation","validationCode":"chains, err := cert.Verify(x509.VerifyOptions{Roots: roots, Intermediates: interPool})\nif err != nil || len(chains) == 0 || len(chains[0]) < 2 {\n\treturn errors.New(\"no parent in chain; issuer missing from MSP\")\n}","typeGuard":null,"tryCatchPattern":"id, err := msp.DeserializeIdentity(raw)\nif err != nil && strings.Contains(err.Error(), \"traverse certificate verification chain\") {\n\t// add issuer cert to MSP and retry\n}","preventionTips":["Ship full chains: leaf + intermediate + root in the appropriate MSP folders","Avoid self-signed end-entity certificates in Fabric networks","Run openssl verify against the MSP CA bundle before importing material"],"tags":["x509","msp","fabric","ecdsa","certificate-chain"],"backgroundTag":"certificate-chain-too-short","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"}