{"record":{"id":"cf535e0055779115","repo":"hyperledger/fabric","slug":"identity-is-not-well-formed","errorCode":null,"errorMessage":"identity is not well formed","messagePattern":"identity is not well formed","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/gossip/mcs.go","lineNumber":308,"sourceCode":"\tif err != nil {\n\t\tmcsLogger.Error(\"failed deserializing identity\", err)\n\t\treturn nil, nil, err\n\t}\n\n\t// Notice that peerIdentity is assumed to be the serialization of an identity.\n\t// So, first step is the identity deserialization and then verify it.\n\n\t// First check against the local MSP.\n\t// If the peerIdentity is in the same organization of this node then\n\t// the local MSP is required to take the final decision on the validity\n\t// of the signature.\n\tlDes := s.deserializer.GetLocalDeserializer()\n\tidentity, err := lDes.DeserializeIdentity(peerIdentity)\n\tif err == nil {\n\t\t// No error means that the local MSP successfully deserialized the identity.\n\t\t// We now check additional properties.\n\t\tif err := lDes.IsWellFormed(sId); err != nil {\n\t\t\treturn nil, nil, errors.Wrap(err, \"identity is not well formed\")\n\t\t}\n\t\t// TODO: The following check will be replaced by a check on the organizational units\n\t\t// when we allow the gossip network to have organization unit (MSP subdivisions)\n\t\t// scoped messages.\n\t\t// The following check is consistent with the SecurityAdvisor#OrgByPeerIdentity\n\t\t// implementation.\n\t\t// TODO: Notice that the following check saves us from the fact\n\t\t// that DeserializeIdentity does not yet enforce MSP-IDs consistency.\n\t\t// This check can be removed once DeserializeIdentity will be fixed.\n\t\tif identity.GetMSPIdentifier() == s.deserializer.GetLocalMSPIdentifier() {\n\t\t\t// Check identity validity\n\n\t\t\t// Notice that at this stage we don't have to check the identity\n\t\t\t// against any channel's policies.\n\t\t\t// This will be done by the caller function, if needed.\n\t\t\treturn identity, nil, identity.Validate()\n\t\t}\n\t}","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/gossip/mcs.go#L290-L326","documentation":"The local MSP successfully deserialized the peer identity, but IsWellFormed on the local deserializer rejected it: the identity does not satisfy structural/organizational requirements (e.g., missing organizational units, disallowed cert properties). The raw MSP error is wrapped with this message. This check prevents identities that parse but are not acceptable for gossip security from being trusted.","triggerScenarios":"getValidatedIdentity path (ValidateIdentity/Verify/Expiration) with an identity whose properties fail lDes.IsWellFormed — wrong OU configuration, certificates not matching the local MSP's expectations, or identities from a peer MSP with mismatched configuration.","commonSituations":"MSP configuration drift after network re-organization (OU changes, NodeOUs enabled on one peer but not the other); certificates issued with SAN/OU fields the local MSP rejects; mixed Fabric versions where identity well-formedness rules differ; wrong crypto material deployed to a peer.","solutions":["Read the wrapped cause under 'identity is not well formed' in peer logs for the exact MSP rejection reason.","Align OU/NodeOUs settings in config.yaml of the relevant MSPs across all peers.","Re-issue/re-enroll the offending peer's certificates so they match the MSP's requirements.","Refresh local MSP definitions from the channel config to pick up updated org MSP settings.","Ensure all peers run compatible Fabric versions with consistent identity validation rules."],"exampleFix":"// before: trusting any deserializable identity\nif _, _, err := cryptoService.getValidatedIdentity(peerIdentity); err != nil { ... }\n// after: surface the well-formedness failure clearly for operators\nif _, _, err := cryptoService.getValidatedIdentity(peerIdentity); err != nil {\n    return fmt.Errorf(\"peer identity rejected by local MSP (check OUs/certs): %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// no caller-side check can fully predict MSP well-formedness; ensure identity is non-empty first\nif len(peerIdentity) == 0 {\n    return fmt.Errorf(\"empty identity\")\n}","typeGuard":null,"tryCatchPattern":"if err := cryptoService.ValidateIdentity(peerIdentity); err != nil {\n    if strings.Contains(err.Error(), \"identity is not well formed\") {\n        log.Warnf(\"peer identity rejected by local MSP; check OU/NodeOUs config and cert issuance: %v\", err)\n        return errUntrustedPeer\n    }\n    return err\n}","preventionTips":["Keep MSP config.yaml (NodeOUs/OU settings) identical across orgs and peers","Re-enroll peers after certificate templates or OU rules change","Sync local MSP definitions from channel config after org updates","Pin compatible Fabric versions so identity well-formedness rules match"],"tags":["hyperledger-fabric","msp","identity","well-formedness","certificates"],"backgroundTag":"identity-not-well-formed","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"}