{"record":{"id":"909187053f961cad","repo":"hyperledger/fabric","slug":"signer-must-be-the-same-as-the-one-referenced-in-t","errorCode":null,"errorMessage":"signer must be the same as the one referenced in the header","messagePattern":"signer must be the same as the one referenced in the header","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/txutils.go","lineNumber":175,"sourceCode":"\t// the original payload\n\tpPayl, err := UnmarshalChaincodeProposalPayload(proposal.Payload)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// check that the signer is the same that is referenced in the header\n\tsignerBytes, err := signer.Serialize()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tshdr, err := UnmarshalSignatureHeader(hdr.SignatureHeader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !bytes.Equal(signerBytes, shdr.Creator) {\n\t\treturn nil, errors.New(\"signer must be the same as the one referenced in the header\")\n\t}\n\n\t// ensure that all actions are bitwise equal and that they are successful\n\tvar a1 []byte\n\tfor n, r := range resps {\n\t\tif r.Response.Status < 200 || r.Response.Status >= 400 {\n\t\t\treturn nil, errors.Errorf(\"proposal response was not successful, error code %d, msg %s\", r.Response.Status, r.Response.Message)\n\t\t}\n\n\t\tif n == 0 {\n\t\t\ta1 = r.Payload\n\t\t\tcontinue\n\t\t}\n\n\t\tif !bytes.Equal(a1, r.Payload) {\n\t\t\treturn nil, errors.Errorf(\"ProposalResponsePayloads do not match (base64): '%s' vs '%s'\",\n\t\t\t\tb64.StdEncoding.EncodeToString(r.Payload), b64.StdEncoding.EncodeToString(a1))\n\t\t}","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/txutils.go#L157-L193","documentation":"CreateSignedTx compares the serialized signer identity with the Creator in the proposal's SignatureHeader and rejects mismatched identities. The transaction must be signed by the same identity that originally created the proposal; a different signer would produce an invalid transaction.","triggerScenarios":"Calling CreateSignedTx with a Signer whose serialized identity (creator bytes) differs from proposal.Header.SignatureHeader.Creator — e.g. a second client instance, a different MSP principal, or a proposal reused across users.","commonSituations":"Multi-user applications mixing up identities; proposals deserialized and re-signed by a gateway/admin identity; tests reusing a proposal captured from another signer; identity serialization differences across MSP versions/peers.","solutions":["Sign the transaction with the same identity that created the proposal (pass the original creator's Signer)","If a different identity must sign, regenerate the proposal with that identity instead of reusing","Verify the MSP identity configuration matches the one used at proposal creation","In tests, construct proposal and signature with the same signer helper"],"exampleFix":"// before\notherSigner, _ := adminMSP.GetDefaultSigningIdentity()\nenv, err := protoutil.CreateSignedTx(proposal, otherSigner, resps...) // proposal made by user\n// after\nuserSigner, err := userMSP.GetDefaultSigningIdentity() // same identity as proposal creator\nenv, err := protoutil.CreateSignedTx(proposal, userSigner, resps...)","handlingStrategy":"validation","validationCode":"func verifySignerMatchesProposal(signer protoutil.Signer, prop *peer.Proposal) error {\n    shdr := &common.SignatureHeader{}\n    if err := proto.Unmarshal(prop.Header, shdr); err != nil {\n        return err\n    }\n    signerBytes, err := signer.Serialize()\n    if err != nil {\n        return err\n    }\n    if !bytes.Equal(signerBytes, shdr.Creator) {\n        return fmt.Errorf(\"signer does not match proposal creator\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := verifySignerMatchesProposal(signer, proposal); err != nil {\n    return nil, err\n}\ntx, err := protoutil.CreateSignedTx(proposal, signer, resps...)","preventionTips":["Keep the proposal and its signer in the same context/session object","Never reuse proposals across users or identities","Compare identity serialization if switching between MSP implementations"],"tags":["signing","identity","hyperledger-fabric","identity-mismatch"],"backgroundTag":"signer-identity-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"}