{"record":{"id":"bbfe0e4263effbfc","repo":"hyperledger/fabric","slug":"creator-is-empty","errorCode":null,"errorMessage":"creator is empty","messagePattern":"creator is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/endorser/msgvalidation.go","lineNumber":153,"sourceCode":"\t\t// transaction, so any other header type seems like it ought to be an error... oh well.\n\n\tdefault:\n\t\treturn errors.Errorf(\"invalid header type %s\", common.HeaderType(up.ChannelHeader.Type))\n\t}\n\n\t// ensure the epoch is 0\n\tif up.ChannelHeader.Epoch != 0 {\n\t\treturn errors.Errorf(\"epoch is non-zero\")\n\t}\n\n\t// ensure that there is a nonce\n\tif len(up.SignatureHeader.Nonce) == 0 {\n\t\treturn errors.Errorf(\"nonce is empty\")\n\t}\n\n\t// ensure that there is a creator\n\tif len(up.SignatureHeader.Creator) == 0 {\n\t\treturn errors.New(\"creator is empty\")\n\t}\n\n\texpectedTxID := protoutil.ComputeTxID(up.SignatureHeader.Nonce, up.SignatureHeader.Creator)\n\tif up.TxID() != expectedTxID {\n\t\treturn errors.Errorf(\"incorrectly computed txid '%s' -- expected '%s'\", up.TxID(), expectedTxID)\n\t}\n\n\tif up.SignedProposal.ProposalBytes == nil {\n\t\treturn errors.Errorf(\"empty proposal bytes\")\n\t}\n\n\tif up.SignedProposal.Signature == nil {\n\t\treturn errors.Errorf(\"empty signature bytes\")\n\t}\n\n\t// get the identity of the creator\n\tcreator, err := idDeserializer.DeserializeIdentity(up.SignatureHeader.Creator)\n\tif err != nil {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/endorser/msgvalidation.go#L135-L171","documentation":"The proposal's SignatureHeader.Creator field (the serialized identity of the submitting client) is empty. The endorser needs the creator to verify the signature, determine the MSP, and compute the transaction ID. An empty creator means the proposal cannot be attributed or authenticated.","triggerScenarios":"ProcessProposal -> preProcess -> Validate on a SignedProposal whose SignatureHeader.Creator is a zero-length byte slice — the client identity was never serialized into the header.","commonSituations":"Clients that never call the SDK's identity/context resolution, wallet/identity not loaded before building the proposal, test harnesses omitting the creator, msp serialization failures swallowed earlier.","solutions":["Load the user identity (cert + key from the wallet/MSP) before building the proposal so Creator is the serialized SigningIdentity.","Set SignatureHeader.Creator to the marshaled identity protobuf (mspprotos.SerializedIdentity with Mspid and IdBytes).","Check the SDK context/user is properly initialized and enrolled for the target organization."],"exampleFix":"// before\nshdr := &common.SignatureHeader{Nonce: nonce}\n// after\nsid, _ := proto.Marshal(&mspprotos.SerializedIdentity{Mspid: \"Org1MSP\", IdBytes: certPEM})\nshdr := &common.SignatureHeader{Nonce: nonce, Creator: sid}","handlingStrategy":"validation","validationCode":"if len(shdr.Creator) == 0 {\n    return errors.New(\"creator identity required: marshal SerializedIdentity into SignatureHeader.Creator\")\n}","typeGuard":"func hasCreator(sh *common.SignatureHeader) bool {\n    return sh != nil && len(sh.Creator) > 0\n}","tryCatchPattern":null,"preventionTips":["Load wallet/user identity before constructing proposals","Fail fast if identity resolution returns empty bytes","Test with a real enrolled identity, not placeholder headers"],"tags":["hyperledger-fabric","endorser","identity","signature-header"],"backgroundTag":"empty-creator-identity","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"}