{"record":{"id":"1eb332e1293cb108","repo":"hyperledger/fabric","slug":"failed-unmarshaling-identity-s","errorCode":null,"errorMessage":"failed unmarshaling identity %s","messagePattern":"failed unmarshaling identity (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/crypto/sanitize.go","lineNumber":28,"sourceCode":"\t\"crypto/ecdsa\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"encoding/pem\"\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/hyperledger/fabric-lib-go/bccsp/utils\"\n\t\"github.com/hyperledger/fabric-protos-go-apiv2/msp\"\n\t\"github.com/pkg/errors\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// SanitizeIdentity sanitizes the signature scheme of the identity\nfunc SanitizeIdentity(identity []byte) ([]byte, error) {\n\tsID := &msp.SerializedIdentity{}\n\tif err := proto.Unmarshal(identity, sID); err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed unmarshaling identity %s\", string(identity))\n\t}\n\n\tfinalPEM, err := SanitizeX509Cert(sID.IdBytes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsID.IdBytes = finalPEM\n\n\treturn proto.Marshal(sID)\n}\n\n// SanitizeX509Cert sanitizes an X.509 certificate to ensure that the ECDSA signature uses a \"low-S\" value.\nfunc SanitizeX509Cert(initialPEM []byte) ([]byte, error) {\n\tder, _ := pem.Decode(initialPEM)\n\tif der == nil {\n\t\treturn nil, errors.Errorf(\"failed to PEM decode identity bytes: %s\", string(initialPEM))\n\t}","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/crypto/sanitize.go#L10-L46","documentation":"SanitizeIdentity unmarshals the input bytes as an msp.SerializedIdentity proto. If the bytes are not a valid SerializedIdentity, the unmarshal error is wrapped with 'failed unmarshaling identity %s' (embedding the raw identity string).","triggerScenarios":"Calling SanitizeIdentity with bytes that are not a protobuf SerializedIdentity — e.g. a bare PEM/DER certificate, an X.509 identity in a non-msp format, or corrupted/truncated identity bytes.","commonSituations":"Passing raw certificate PEM instead of the fabric SerializedIdentity envelope; identities from a different fabric version or a peer's identity store that changed format; gossip receiving garbage/foreign identity payloads from misconfigured nodes.","solutions":["Ensure the input is a serialized msp.SerializedIdentity (MSPid + IdBytes PEM), not a bare certificate","Check where the identity bytes came from — re-export them from the MSP folder via proper fabric tooling","Inspect the embedded raw identity in the message to spot obvious corruption or wrong format","Verify both peers are on compatible fabric versions so identity serialization matches"],"exampleFix":"// before\nsanitized, err := crypto.SanitizeIdentity(certPEM)\n// after\nsID := &msp.SerializedIdentity{Mspid: mspID, IdBytes: certPEM}\nidentity, _ := proto.Marshal(sID)\nsanitized, err := crypto.SanitizeIdentity(identity)","handlingStrategy":"validation","validationCode":"func looksLikeSerializedIdentity(b []byte) bool {\n    sID := &msp.SerializedIdentity{}\n    return proto.Unmarshal(b, sID) == nil && len(sID.IdBytes) > 0 && strings.HasPrefix(string(sID.IdBytes), \"-----BEGIN\")\n}","typeGuard":null,"tryCatchPattern":"sanitized, err := crypto.SanitizeIdentity(identity)\nif err != nil && strings.Contains(err.Error(), \"failed unmarshaling identity\") {\n    // input was not a SerializedIdentity; re-serialize from MSP files\n}","preventionTips":["Only pass proto-marshaled msp.SerializedIdentity values, never raw PEM","Obtain identities via fabric's MSP/identity APIs rather than manual file reads","Validate identity bytes at ingestion boundaries (gossip/service entry points)"],"tags":["hyperledger-fabric","identity","protobuf","msp"],"backgroundTag":"identity-unmarshal-failed","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"}