hyperledger/fabric · error

request id is empty

Error message

request id is empty

What it means

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.

Source

Thrown at orderer/consensus/smartbft/verifier.go:200

	switch req.chHdr.Type {
	case int32(cb.HeaderType_CONFIG):
	case int32(cb.HeaderType_ORDERER_TRANSACTION):
		return types.RequestInfo{}, fmt.Errorf("orderer transactions are not supported in v3")
	case int32(cb.HeaderType_ENDORSER_TRANSACTION):
	default:
		return types.RequestInfo{}, errors.Errorf("transaction of type %s is not allowed to be included in blocks", cb.HeaderType_name[req.chHdr.Type])
	}

	if req.chHdr.Type == int32(cb.HeaderType_CONFIG) {
		err = v.ConfigValidator.ValidateConfig(req.envelope)
		if err != nil {
			v.Logger.Errorf("Error verifying config update: %v", err)
			return types.RequestInfo{}, err
		}

		reqID := v.ReqInspector.RequestID(rawRequest)
		if v.ReqInspector.isEmpty(reqID) {
			return types.RequestInfo{}, errors.Errorf("request id is empty")
		}

		return reqID, nil
	}

	return v.ReqInspector.requestIDFromSigHeader(req.sigHdr)
}

// VerifyConsenterSig verifies consenter signature
func (v *Verifier) VerifyConsenterSig(signature types.Signature, prop types.Proposal) ([]byte, error) {
	id2Identity := v.RuntimeConfig.Load().(RuntimeConfig).ID2Identities

	identity, exists := id2Identity[signature.ID]
	if !exists {
		return nil, errors.Errorf("node with id of %d doesn't exist", signature.ID)
	}

	sig := &Signature{}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the client envelope: ensure the payload header (txid) is populated before submitting
  2. Confirm the channel's ReqInspector matches the actual request format in use
  3. Log and re-encode the rawRequest bytes to check it is non-empty and correctly serialized
  4. If a proxy or intermediary modifies requests, verify it does not drop header fields

Example fix

// before: client submits envelope with empty txid
env.Payload = someBytes // header txid missing
// after: ensure txid computed and set
txid, _ := protoutil.ComputeTxID(sdkRandHeader)
payload.Header.ChannelHeader.TxId = txid
Defensive patterns

Strategy: validation

Validate before calling

if len(rawRequest) == 0 { return errors.New("empty request") }
id := reqInspector.RequestID(rawRequest)
if id.isEmpty(id) { return errors.New("request has empty id; check envelope header/txid") }

Type guard

func hasRequestID(req []byte, insp ReqInspector) bool { return !insp.isEmpty(insp.RequestID(req)) }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/6adf32c1c240e110. Report an issue: GitHub.