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
- Submit only ENDORSER_TRANSACTION (application) or CONFIG envelopes to BFT channels
- Fix the client code/SDK to set cb.HeaderType_ENDORSER_TRANSACTION for regular transactions
- 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
- Only send endorsed transactions or config updates
- Validate envelope headers with configtxlator before submit
- Avoid custom envelope-crafting code; use maintained SDKs
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
- only endorser transactions can be sent with other transactio
- no config found in envelope
- consenter options type mismatch
- channel header not found in the envelope
- badly formatted message, cannot extract channel
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/508614e0f6edf76b.
Report an issue: GitHub.