hyperledger/fabric · error
ERROR - only a single deliver source is currently supported
Error message
ERROR - only a single deliver source is currently supported
What it means
InitCmdFactory builds the client factory for peer channel commands. A command can take its block/deliver stream from either the peer's deliver service or the ordering service — never both. Receiving both flags true indicates a developer bug in wiring a new command, so it refuses to proceed.
Source
Thrown at internal/peer/channel/channel.go:136
GetOldestBlock() (*cb.Block, error)
GetNewestBlock() (*cb.Block, error)
Close() error
}
// ChannelCmdFactory holds the clients used by ChannelCmdFactory
type ChannelCmdFactory struct {
EndorserClient pb.EndorserClient
Signer msp.SigningIdentity
BroadcastClient common.BroadcastClient
DeliverClient deliverClientIntf
BroadcastFactory BroadcastClientFactory
}
// InitCmdFactory init the ChannelCmdFactory with clients to endorser and orderer based on the given parameters
func InitCmdFactory(isEndorserRequired, isPeerDeliverRequired, isOrdererRequired bool) (*ChannelCmdFactory, error) {
if isPeerDeliverRequired && isOrdererRequired {
// this is likely a bug during development caused by adding a new cmd
return nil, errors.New("ERROR - only a single deliver source is currently supported")
}
var err error
cf := &ChannelCmdFactory{}
cf.Signer, err = common.GetDefaultSignerFnc()
if err != nil {
return nil, errors.WithMessage(err, "error getting default signer")
}
cf.BroadcastFactory = func() (common.BroadcastClient, error) {
return common.GetBroadcastClientFnc()
}
// for join and list, we need the endorser as well
if isEndorserRequired {
// creating an EndorserClient with these empty parameters will create a
// connection using the values of "peer.address" andView on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the call site to pass exactly one deliver source: e.g. InitCmdFactory(EndorserRequired, PeerDeliverRequired, OrdererNotRequired) or (..., PeerDeliverNotRequired, OrdererRequired).
- Review which service should serve blocks for your command: peer deliver for existing channels, orderer for channel creation.
- Write a unit test asserting the flag combination for your command.
Example fix
// before factory, err := channel.InitCmdFactory(channel.EndorserRequired, channel.PeerDeliverRequired, channel.OrdererRequired) // after factory, err := channel.InitCmdFactory(channel.EndorserRequired, channel.PeerDeliverRequired, channel.OrdererNotRequired)
Defensive patterns
Strategy: validation
Validate before calling
// caller-side check when invoking InitCmdFactory
if isPeerDeliverRequired && isOrdererRequired {
return nil, errors.New("choose exactly one deliver source: peer deliver OR orderer")
} Try / catch
cf, err := channel.InitCmdFactory(isEndorser, isPeerDeliver, isOrderer)
if err != nil {
return fmt.Errorf("init channel factory: %w", err)
} Prevention
- Keep a table of flag combos per channel subcommand.
- Add unit tests asserting InitCmdFactory rejects both-true combos.
- Review any new channel command for exactly one deliver source.
When it happens
Trigger: Calling InitCmdFactory with isPeerDeliverRequired=true AND isOrdererRequired=true — typically when adding or modifying a channel subcommand and passing the wrong boolean combination.
Common situations: Contributing a new `peer channel` subcommand; refactoring an existing command's deliver source; copying an InitCmdFactory call and flipping flags incorrectly.
Related errors
- chaincode type not supported: %s
- failed to copy metadataDir directory folder: %s
- error unmarshalling YAML file %s: %s
- no endpoints
- subpolicy number %d type %T of policy %s is not convertible
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/68f2c0480ad3f4a1.
Report an issue: GitHub.