hyperledger/fabric · error

transaction of type %s is not allowed to be included in bloc

Error message

transaction of type %s is not allowed to be included in blocks

What it means

Any request whose header type is not CONFIG, ORDERER_TRANSACTION, or ENDORSER_TRANSACTION falls into the default branch and is rejected — the BFT block format only permits known transaction types. The offending type name is interpolated from cb.HeaderType_name.

Source

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

	if err != nil {
		return types.RequestInfo{}, errors.Wrap(err, "access denied")
	}

	if noConfigAllowed && req.chHdr.Type != int32(cb.HeaderType_ENDORSER_TRANSACTION) {
		return types.RequestInfo{}, errors.Errorf("only endorser transactions can be sent with other transactions")
	}

	if req.chHdr.ChannelId != v.Channel {
		return types.RequestInfo{}, errors.Errorf("request is for channel %s but expected channel %s", req.chHdr.ChannelId, v.Channel)
	}

	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)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Submit only ENDORSER_TRANSACTION (application) or CONFIG envelopes to BFT channels
  2. Fix the client code/SDK to set cb.HeaderType_ENDORSER_TRANSACTION for regular transactions
  3. Inspect the envelope header with configtxlator decode to find the offending type and rebuild it
Defensive patterns

Strategy: validation

Validate before calling

switch hdr.Type {
case int32(cb.HeaderType_CONFIG), int32(cb.HeaderType_ENDORSER_TRANSACTION):
    // ok
default:
    return fmt.Errorf("type %s not allowed in BFT blocks", cb.HeaderType_name[hdr.Type])
}

Type guard

func allowedInBFT(t int32) bool {
    _, ok := map[int32]bool{
        int32(cb.HeaderType_CONFIG): true,
        int32(cb.HeaderType_ENDORSER_TRANSACTION): true,
    }[t]
    return ok
}

Try / catch

if _, err := VerifyRequest(req); err != nil {
    if strings.Contains(err.Error(), "not allowed to be included in blocks") {
        // decode header and rebuild envelope with correct type
    }
}

Prevention

When it happens

Trigger: Submitting envelopes with unusual header types (e.g. DELIVER_SEEK_INFO, PEEr_RESOURCE_UPDATE or an unknown numeric type) to the SmartBFT request path.

Common situations: Custom or buggy client tooling crafting envelopes with wrong header types; SDK misuse building raw envelopes; corrupted headers after tampering or bad serialization.

Related errors


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