{"record":{"id":"1ee263b9f2e670aa","repo":"hyperledger/fabric","slug":"identity-in-signature-header-does-not-match-expect","errorCode":null,"errorMessage":"identity in signature header does not match expected identity","messagePattern":"identity in signature header does not match expected identity","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/verifier.go","lineNumber":399,"sourceCode":"\t// BlockHeader          []byte\n\t// OrdererBlockMetadata []byte\n\n\t// Ensure block header is equal\n\tif !bytes.Equal(prop.Header, sig.BlockHeader) {\n\t\tv.Logger.Errorf(\"Expected block header %s but got %s\", base64.StdEncoding.EncodeToString(prop.Header),\n\t\t\tbase64.StdEncoding.EncodeToString(sig.BlockHeader))\n\t\treturn errors.Errorf(\"mismatched block header\")\n\t}\n\n\t// Ensure signature header matches the identity\n\tsigHdr := &cb.IdentifierHeader{}\n\tif err := proto.Unmarshal(sig.IdentifierHeader, sigHdr); err != nil {\n\t\treturn errors.Wrap(err, \"malformed signature header\")\n\t}\n\tif identityID != uint64(sigHdr.Identifier) {\n\t\tv.Logger.Warnf(\"Expected identity %d but got %d\", identityID,\n\t\t\tsigHdr.Identifier)\n\t\treturn errors.Errorf(\"identity in signature header does not match expected identity\")\n\t}\n\n\t// Ensure orderer block metadata's consenter MD matches the proposal\n\tordererMD := &cb.OrdererBlockMetadata{}\n\tif err := proto.Unmarshal(sig.OrdererBlockMetadata, ordererMD); err != nil {\n\t\treturn errors.Wrap(err, \"malformed orderer metadata in signature\")\n\t}\n\n\tif !bytes.Equal(ordererMD.ConsenterMetadata, prop.Metadata) {\n\t\tv.Logger.Warnf(\"Expected consenter metadata %s but got %s in proposal\",\n\t\t\tbase64.StdEncoding.EncodeToString(ordererMD.ConsenterMetadata), base64.StdEncoding.EncodeToString(prop.Metadata))\n\t\treturn errors.Errorf(\"consenter metadata in OrdererBlockMetadata doesn't match proposal\")\n\t}\n\n\tblock, err := ProposalToBlock(prop)\n\tif err != nil {\n\t\tv.Logger.Warnf(\"got malformed proposal: %v\", err)\n\t\treturn err","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/verifier.go#L381-L417","documentation":"The IdentifierHeader inside a consenter signature must carry the same identity number as the identity that supposedly produced the signature (identityID, derived from the signature verification with the node's channel membership). This error means the signature's declared consenter ID does not match the identity that actually signed — a signature attributed to the wrong consenter, or a node using the wrong TLS/channel identity.","triggerScenarios":"VerifyConsenterSig -> verifySignatureIsBoundToProposal: identityID != uint64(sigHdr.Identifier). Triggered when a signature arrives claiming to be from consenter N but its certificate/identity resolves to a different slot number, or the IdentifierHeader was built with a stale/wrong self ID.","commonSituations":"Consenter order changed in the channel config (e.g. a node removed/added) while another node cached the old identity-to-slot mapping; a node restarted with the wrong TLS keypair/certificate; configuration change not yet propagated to all nodes; a misbehaving node signing with another's ID.","solutions":["Ensure all consenters have processed the latest channel config so identity-to-ID mappings agree, and restart nodes whose mapping is stale.","Verify each ordering node's TLS certificates and local MSP match its configured consenter entry.","Trigger a view change after any channel membership change so signatures are regenerated with correct identifiers.","Check for membership churn (nodes added/removed) around the time of the error and re-verify the consenter list ordering."],"exampleFix":"// before: mapping skew after membership change\nidentityID = 3 (from cert); sigHdr.Identifier = 2 -> error\n// after: all nodes agree on identity mapping\nidentityID = 3; sigHdr.Identifier = 3","handlingStrategy":"validation","validationCode":"sigHdr := &cb.IdentifierHeader{}\nif err := proto.Unmarshal(sig.IdentifierHeader, sigHdr); err != nil { return err }\nif identityID != uint64(sigHdr.Identifier) {\n    // membership mapping is stale; refresh channel config before trusting signatures\n    return fmt.Errorf(\"identity %d != header id %d\", identityID, sigHdr.Identifier)\n}","typeGuard":null,"tryCatchPattern":"if err := verifySig(sig); err != nil && strings.Contains(err.Error(), \"identity in signature header\") {\n    refreshMembershipMapping()\n    return err\n}","preventionTips":["Apply channel config updates atomically across all orderers","Restart orderers after membership changes so identity mappings reload","Audit TLS cert/MSP configuration against each consenter's channel entry"],"tags":["hyperledger-fabric","smartbft","identity","signature-verification"],"backgroundTag":"identity-mapping-mismatch","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"}