hyperledger/fabric · error
cannot create BFT block deliverer
Error message
cannot create BFT block deliverer
What it means
Raised in BFTSynchronizer.synchronize when s.createBFTDeliverer(startHeight, myEndpoint) returns an error, wrapped as 'cannot create BFT block deliverer'. The BFT deliverer wires up the block-fetching machinery (BlockPuller/deliver clients) that streams blocks into the sync buffer; creation failures are configuration, TLS, or dialing problems detected before fetching starts.
Source
Thrown at orderer/consensus/smartbft/synchronizer_bft.go:109
if err != nil {
return nil, errors.Wrapf(err, "cannot get detect target height")
}
startHeight := s.Support.Height()
if startHeight >= targetHeight {
return nil, errors.Errorf("already at target height of %d", targetHeight)
}
// === Create a buffer to accept the blocks delivered from the BFTDeliverer.
capacityBlocks := max(uint(s.LocalConfigCluster.ReplicationBufferSize)/uint(s.Support.SharedConfig().BatchSize().AbsoluteMaxBytes), 100)
s.mutex.Lock()
s.syncBuff = NewSyncBuffer(capacityBlocks)
s.mutex.Unlock()
// === Create the BFT block deliverer and start a go-routine that fetches block and inserts them into the syncBuffer.
bftDeliverer, err := s.createBFTDeliverer(startHeight, myEndpoint)
if err != nil {
return nil, errors.Wrapf(err, "cannot create BFT block deliverer")
}
go bftDeliverer.DeliverBlocks()
defer bftDeliverer.Stop()
// === Loop on sync-buffer and pull blocks, writing them to the ledger, returning the last block pulled.
lastPulledBlock, err := s.getBlocksFromSyncBuffer(startHeight, targetHeight)
if err != nil {
return nil, errors.Wrapf(err, "failed to get any blocks from SyncBuffer")
}
decision := s.BlockToDecision(lastPulledBlock)
s.Logger.Infof("Returning decision from block [%d], decision: %+v", lastPulledBlock.GetHeader().GetNumber(), decision)
return decision, nil
}
// detectTargetHeight probes remote endpoints and detects what is the target height this node needs to reach. It also
// detects the self-endpoint.View on GitHub (pinned to 2736b63f8f)
Solutions
- Read the wrapped inner error to see whether it is a TLS, dialer, or crypto failure
- Validate orderer.yaml cluster settings: TLS.Enabled, client cert/key paths, dial timeouts
- Ensure the cluster client certificate/key pair is valid and its CA is trusted in the channel config
- Compare with a working node's configuration and fix deviations
Example fix
// before (orderer.yaml)
cluster:
clientCertificate:
File: wrong-path.pem
// after
cluster:
clientCertificate:
File: /var/hyperledger/orderer/tls/server.crt
clientPrivateKey:
File: /var/hyperledger/orderer/tls/server.key Defensive patterns
Strategy: validation
Validate before calling
// Validate cluster config before starting the orderer
if _, err := tls.LoadX509KeyPair(cluster.ClientCertificate.File, cluster.ClientPrivateKey.File); err != nil {
log.Fatalf("invalid cluster client keypair: %v", err)
} Try / catch
resp := bftSynchronizer.Sync()
// creation failures are deterministic (config), not retriable — fail fast and alert
if syncFailed(resp) && delivererCreationFailedInLogs() {
alertOperator("BFT deliverer creation failed: fix orderer.yaml cluster section")
} Prevention
- Validate orderer.yaml cluster TLS paths and permissions at startup/deployment
- Use config linting or dry-run to catch malformed cluster sections
- Ensure the cluster client cert is trusted by all peers' channel CAs
- Keep crypto material generation and deployment automated to avoid path drift
When it happens
Trigger: createBFTDeliverer fails while constructing the deliverer: BlockPuller creation errors (invalid cluster TLS config, dialer misconfiguration, crypto provider issues) — happens after target height detection succeeded but before DeliverBlocks is started.
Common situations: Malformed orderer.yaml cluster section (bad TLS cert/key paths, wrong dial timeout); missing or invalid MSP/TLS material for the cluster client; earlier height probing passed but deliverer-specific configuration is wrong.
Related errors
- cannot get HeightsByEndpoints
- cannot get create BlockPuller
- cannot get HeightsByEndpoints
- pending config does not match calculated expected config
- without a system channel, a follower should have been create
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/9253a0015f6d6613.
Report an issue: GitHub.