hyperledger/fabric · error
failed unmarshaling identity %s
Error message
failed unmarshaling identity %s
What it means
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).
Source
Thrown at common/crypto/sanitize.go:28
"crypto/ecdsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"math/big"
"time"
"github.com/hyperledger/fabric-lib-go/bccsp/utils"
"github.com/hyperledger/fabric-protos-go-apiv2/msp"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
)
// SanitizeIdentity sanitizes the signature scheme of the identity
func SanitizeIdentity(identity []byte) ([]byte, error) {
sID := &msp.SerializedIdentity{}
if err := proto.Unmarshal(identity, sID); err != nil {
return nil, errors.Wrapf(err, "failed unmarshaling identity %s", string(identity))
}
finalPEM, err := SanitizeX509Cert(sID.IdBytes)
if err != nil {
return nil, err
}
sID.IdBytes = finalPEM
return proto.Marshal(sID)
}
// SanitizeX509Cert sanitizes an X.509 certificate to ensure that the ECDSA signature uses a "low-S" value.
func SanitizeX509Cert(initialPEM []byte) ([]byte, error) {
der, _ := pem.Decode(initialPEM)
if der == nil {
return nil, errors.Errorf("failed to PEM decode identity bytes: %s", string(initialPEM))
}View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before
sanitized, err := crypto.SanitizeIdentity(certPEM)
// after
sID := &msp.SerializedIdentity{Mspid: mspID, IdBytes: certPEM}
identity, _ := proto.Marshal(sID)
sanitized, err := crypto.SanitizeIdentity(identity) Defensive patterns
Strategy: validation
Validate before calling
func looksLikeSerializedIdentity(b []byte) bool {
sID := &msp.SerializedIdentity{}
return proto.Unmarshal(b, sID) == nil && len(sID.IdBytes) > 0 && strings.HasPrefix(string(sID.IdBytes), "-----BEGIN")
} Try / catch
sanitized, err := crypto.SanitizeIdentity(identity)
if err != nil && strings.Contains(err.Error(), "failed unmarshaling identity") {
// input was not a SerializedIdentity; re-serialize from MSP files
} Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed unmarshalling peer's identity
- Could not serialize the signing identity: %s
- access denied: channel [%s] creator org unknown, creator is
- Invalid Proposal's SignatureHeader during check policy on ch
- Failed deserializing proposal creator during channelless che
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/1eb332e1293cb108.
Report an issue: GitHub.