hyperledger/fabric · error
unexpected block type: %T
Error message
unexpected block type: %T
What it means
BlockIterator.Next in internal/pkg/gateway/event asserts that the underlying ledger iterator yields *common.Block. Any other concrete type behind the QueryResultsIterator interface reaches the default branch and produces this errors.Errorf with the actual Go type. It is an internal invariant check: the gateway event service only expects blocks.
Source
Thrown at internal/pkg/gateway/event/blockiterator.go:34
}
func NewBlockIterator(iterator ledger.ResultsIterator) *BlockIterator {
return &BlockIterator{
ledgerIter: iterator,
}
}
func (iter *BlockIterator) Next() (*Block, error) {
result, err := iter.ledgerIter.Next()
if err != nil {
return nil, err
}
switch block := result.(type) {
case *common.Block:
return NewBlock(block), nil
default:
return nil, errors.Errorf("unexpected block type: %T", result)
}
}
func (iter *BlockIterator) Close() {
iter.ledgerIter.Close()
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the iterator was created from a ledger query that returns blocks (GetBlocksIterator), not kv/query results
- Check for custom or patched ledger components returning non-standard result types
- Update/align Fabric component versions so the ledger and gateway event service agree on the block type
Example fix
// before iter := ledger.NewQueryIterator(...) // returns KV results // after iter, _ := ledger.GetBlocksIterator() // returns *common.Block entries
Defensive patterns
Strategy: type-guard
Validate before calling
// before consuming, ensure the iterator source yields blocks // e.g. use ledger.GetBlocksIterator rather than a generic state/query iterator
Type guard
func asBlock(v interface{}) (*fabric.Block, bool) {
b, ok := v.(*common.Block)
return fabric.NewBlock(b), ok
} Try / catch
blk, err := iter.Next()
if err != nil {
if strings.Contains(err.Error(), "unexpected block type") {
log.Printf("iterator yielded non-block result: %v", err)
return errBlockIteratorMisused
}
return err
} Prevention
- Use ledger block iterators (GetBlocksIterator) for the gateway event service
- Do not swap in mocks or custom iterators returning other result types in production
- Keep Fabric components at compatible versions so iterator result types are consistent
When it happens
Trigger: Registering/iterating a chaincode event or filtered-block stream where the ledger iterator returns a value that is neither *common.Block nor already a fabric Block — i.e. a type other than *common.Block surfaces from the ledger's QueryResultsIterator.
Common situations: Fabric source modifications or custom ledger/queryresult implementations returning non-block results; mixing iterators across ledgers/components with different result types; test doubles or mocks returning unexpected types.
Related errors
- query iterator not found
- expected QueryResult of either ChaincodeQueryResult or Error
- error getting next element out of private data iterator, nam
- no chaincode name is provided, channel id [%s]
- failed to deserialize proposal response payload
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/1816c40efd518d1e.
Report an issue: GitHub.