hyperledger/fabric · error
response is of type %v, but expected a block
Error message
response is of type %v, but expected a block
What it means
extractBlockFromResponse hits its default case when the DeliverResponse payload Type is not a DeliverResponse_BLOCK — the remote ordering node answered with a status (or nothing block-shaped) instead of the requested block. This means the deliver stream did not deliver what the BlockPuller asked for.
Source
Thrown at orderer/common/cluster/deliver.go:480
return nil, errors.New("block data is nil")
}
if block.Header == nil {
return nil, errors.New("block header is nil")
}
if block.Metadata == nil || len(block.Metadata.Metadata) == 0 {
return nil, errors.New("block metadata is empty")
}
return block, nil
case *orderer.DeliverResponse_Status:
if t.Status == common.Status_FORBIDDEN {
return nil, ErrForbidden
}
if t.Status == common.Status_SERVICE_UNAVAILABLE {
return nil, ErrServiceUnavailable
}
return nil, errors.Errorf("faulty node, received: %v", resp)
default:
return nil, errors.Errorf("response is of type %v, but expected a block", reflect.TypeOf(resp.Type))
}
}
func (p *BlockPuller) seekLastEnvelope() (*common.Envelope, error) {
return protoutil.CreateSignedEnvelopeWithTLSBinding(
common.HeaderType_DELIVER_SEEK_INFO,
p.Channel,
p.Signer,
last(),
int32(0),
uint64(0),
util.ComputeSHA256(p.TLSCert),
)
}
func (p *BlockPuller) seekNextEnvelope(startSeq uint64) (*common.Envelope, error) {
return protoutil.CreateSignedEnvelopeWithTLSBinding(
common.HeaderType_DELIVER_SEEK_INFO,View on GitHub (pinned to 2736b63f8f)
Solutions
- Check the status embedded in the response in the orderer logs to see why a block was not returned
- Re-pull from a different cluster endpoint — the puller retries other endpoints automatically
- Align Fabric versions across all ordering nodes
- Verify the endpoint list in the cluster configuration points at actual consenter nodes of the channel
Defensive patterns
Strategy: type-guard
Validate before calling
if resp.GetType() != orderer.DeliverResponse_BLOCK { log.Printf("got status %v instead of block", resp.GetStatus()) } Type guard
func extractStatus(resp *orderer.DeliverResponse) (common.Status, bool) {
if resp == nil || resp.GetType() != orderer.DeliverResponse_Status { return 0, false }
return resp.GetStatus(), true
} Try / catch
blockResp, err := p.extractBlockFromResponse(resp)
if err != nil {
var status common.Status
if resp.GetType() == orderer.DeliverResponse_Status { status = resp.GetStatus() }
// branch on status or retry another endpoint
return err
} Prevention
- Pin the same Fabric release on every ordering node
- Verify endpoint lists against the channel's consenter set
- Log full DeliverResponse contents for diagnosis
- Test deliver streams after any channel config update
When it happens
Trigger: The remote node returns a DeliverResponse whose Type is DeliverResponse_Status (e.g. NOT_FOUND, BAD_REQUEST, FORBIDDEN not matching the special-cased statuses) instead of a block; a malformed or foreign message on the deliver stream.
Common situations: Requesting a block (e.g. latest config block for eviction detection) from a node that no longer services the channel; fabric binary skew between nodes; corrupted or spoofed responses from a wrong endpoint.
Related errors
- stream %d aborted
- invalid request object
- connection to %d(%s) is in state %s
- faulty node, received: %v
- didn't receive a response within %v
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/15dcd9ea93149618.
Report an issue: GitHub.