{"record":{"id":"6adf32c1c240e110","repo":"hyperledger/fabric","slug":"request-id-is-empty","errorCode":null,"errorMessage":"request id is empty","messagePattern":"request id is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/verifier.go","lineNumber":200,"sourceCode":"\tswitch req.chHdr.Type {\n\tcase int32(cb.HeaderType_CONFIG):\n\tcase int32(cb.HeaderType_ORDERER_TRANSACTION):\n\t\treturn types.RequestInfo{}, fmt.Errorf(\"orderer transactions are not supported in v3\")\n\tcase int32(cb.HeaderType_ENDORSER_TRANSACTION):\n\tdefault:\n\t\treturn types.RequestInfo{}, errors.Errorf(\"transaction of type %s is not allowed to be included in blocks\", cb.HeaderType_name[req.chHdr.Type])\n\t}\n\n\tif req.chHdr.Type == int32(cb.HeaderType_CONFIG) {\n\t\terr = v.ConfigValidator.ValidateConfig(req.envelope)\n\t\tif err != nil {\n\t\t\tv.Logger.Errorf(\"Error verifying config update: %v\", err)\n\t\t\treturn types.RequestInfo{}, err\n\t\t}\n\n\t\treqID := v.ReqInspector.RequestID(rawRequest)\n\t\tif v.ReqInspector.isEmpty(reqID) {\n\t\t\treturn types.RequestInfo{}, errors.Errorf(\"request id is empty\")\n\t\t}\n\n\t\treturn reqID, nil\n\t}\n\n\treturn v.ReqInspector.requestIDFromSigHeader(req.sigHdr)\n}\n\n// VerifyConsenterSig verifies consenter signature\nfunc (v *Verifier) VerifyConsenterSig(signature types.Signature, prop types.Proposal) ([]byte, error) {\n\tid2Identity := v.RuntimeConfig.Load().(RuntimeConfig).ID2Identities\n\n\tidentity, exists := id2Identity[signature.ID]\n\tif !exists {\n\t\treturn nil, errors.Errorf(\"node with id of %d doesn't exist\", signature.ID)\n\t}\n\n\tsig := &Signature{}","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/verifier.go#L182-L218","documentation":"verifyRequest in orderer/consensus/smartbft/verifier.go derives a types.RequestInfo by asking the configured ReqInspector for the request ID of the raw request. If the inspector returns an empty request ID, the verifier refuses the request because SmartBFT cannot identify, sign, or deduplicate a request with no identifier. This is a defensive check so an unidentifiable request never enters consensus.","triggerScenarios":"VerifyRequest (via verifyRequest) is called with a raw request whose bytes, when parsed by ReqInspector.RequestID, yield an empty ID — e.g. an empty payload, a request type the inspector does not recognize, or a txID header field that is empty.","commonSituations":"Clients submitting malformed/empty envelope payloads; a channel whose RequestFilter/ReqInspector is configured for a different message shape (e.g. channel created for a different transaction format); proxy/interceptor code stripping headers; fabric version mismatch where the request format changed.","solutions":["Inspect the client envelope: ensure the payload header (txid) is populated before submitting","Confirm the channel's ReqInspector matches the actual request format in use","Log and re-encode the rawRequest bytes to check it is non-empty and correctly serialized","If a proxy or intermediary modifies requests, verify it does not drop header fields"],"exampleFix":"// before: client submits envelope with empty txid\nenv.Payload = someBytes // header txid missing\n// after: ensure txid computed and set\ntxid, _ := protoutil.ComputeTxID(sdkRandHeader)\npayload.Header.ChannelHeader.TxId = txid","handlingStrategy":"validation","validationCode":"if len(rawRequest) == 0 { return errors.New(\"empty request\") }\nid := reqInspector.RequestID(rawRequest)\nif id.isEmpty(id) { return errors.New(\"request has empty id; check envelope header/txid\") }","typeGuard":"func hasRequestID(req []byte, insp ReqInspector) bool { return !insp.isEmpty(insp.RequestID(req)) }","tryCatchPattern":null,"preventionTips":["Always populate the envelope header txid on the client before submission","Match the ReqInspector configuration to the channel's request format","Add a pre-submit sanity check that the request ID is non-empty","Log raw request bytes on failure to diagnose format drift"],"tags":["smartbft","fabric","request-validation","consensus"],"backgroundTag":"empty-request-id","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"}