hyperledger/fabric · error
global orderer endpoints exist, but can not be used with V3_
Error message
global orderer endpoints exist, but can not be used with V3_0 capability: %v
What it means
Starting with the V3_0 channel capability, per-channel orderer endpoints are used instead of the legacy global Orderer.Addresses list. If configtx.yaml defines global addresses while V3_0 is enabled, NewOrdererGroup rejects the config because those endpoints would be ignored/misplaced in a V3_0 channel. The error lists the offending addresses.
Source
Thrown at internal/configtxgen/encoder/encoder.go:190
channelGroup.Groups[channelconfig.ConsortiumsGroupKey], err = NewConsortiumsGroup(conf.Consortiums)
if err != nil {
return nil, errors.Wrap(err, "could not create consortiums group")
}
}
channelGroup.ModPolicy = channelconfig.AdminsPolicyKey
return channelGroup, nil
}
// NewOrdererGroup returns the orderer component of the channel configuration. It defines parameters of the ordering service
// about how large blocks should be, how frequently they should be emitted, etc. as well as the organizations of the ordering network.
// It sets the mod_policy of all elements to "Admins". This group is always present in any channel configuration.
func NewOrdererGroup(conf *genesisconfig.Orderer, channelCapabilities map[string]bool) (*cb.ConfigGroup, error) {
if conf.OrdererType == "BFT" && !channelCapabilities["V3_0"] {
return nil, errors.Errorf("orderer type BFT must be used with V3_0 channel capability: %v", channelCapabilities)
}
if len(conf.Addresses) > 0 && channelCapabilities["V3_0"] {
return nil, errors.Errorf("global orderer endpoints exist, but can not be used with V3_0 capability: %v", conf.Addresses)
}
ordererGroup := protoutil.NewConfigGroup()
if err := AddOrdererPolicies(ordererGroup, conf.Policies, channelconfig.AdminsPolicyKey); err != nil {
return nil, errors.Wrapf(err, "error adding policies to orderer group")
}
addValue(ordererGroup, channelconfig.BatchSizeValue(
conf.BatchSize.MaxMessageCount,
conf.BatchSize.AbsoluteMaxBytes,
conf.BatchSize.PreferredMaxBytes,
), channelconfig.AdminsPolicyKey)
addValue(ordererGroup, channelconfig.BatchTimeoutValue(conf.BatchTimeout.String()), channelconfig.AdminsPolicyKey)
addValue(ordererGroup, channelconfig.ChannelRestrictionsValue(conf.MaxChannels), channelconfig.AdminsPolicyKey)
if len(conf.Capabilities) > 0 {
addValue(ordererGroup, channelconfig.CapabilitiesValue(conf.Capabilities), channelconfig.AdminsPolicyKey)
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Remove the Addresses: entry under the Orderer section in configtx.yaml; V3_0 takes orderer endpoints from the Orderers config value / per-consenter configuration
- If you need shared endpoints, set them per consenter (TLS certs/host/port in the consenters list) rather than globally
- Regenerate the channel config/genesis block after removing the addresses
Example fix
# before
Orderer:
OrdererType: etcdraft
Addresses:
- orderer.example.com:7050
# after
Orderer:
OrdererType: etcdraft
# Addresses removed for V3_0; endpoints come from consenter config
EtcdRaft:
Consenters:
- Host: orderer.example.com
Port: 7050 Defensive patterns
Strategy: validation
Validate before calling
func validateNoGlobalAddresses(conf *genesisconfig.Orderer, caps map[string]bool) error {
if len(conf.Addresses) > 0 && caps["V3_0"] {
return fmt.Errorf("remove Orderer.Addresses %v when V3_0 capability is enabled", conf.Addresses)
}
return nil
} Type guard
func hasGlobalOrdererAddresses(conf *genesisconfig.Orderer) bool { return len(conf.Addresses) > 0 } Try / catch
group, err := encoder.NewOrdererGroup(conf, caps)
if err != nil && strings.Contains(err.Error(), "global orderer endpoints") {
return fmt.Errorf("delete the Addresses: section under Orderer in configtx.yaml for V3_0: %w", err)
} Prevention
- Remove Orderer.Addresses when migrating any profile to V3_0
- Use per-consenter endpoints (consenter mapping / EtcdRaft Consenters) instead of global ones
- Diff your profile against the current-version sample configtx.yaml after upgrades
When it happens
Trigger: Calling NewOrdererGroup/NewChannelGroup with a genesisconfig.Orderer whose Addresses slice is non-empty AND channelCapabilities["V3_0"] is true — i.e. Orderer.Addresses set in configtx.yaml together with the V3_0 channel capability.
Common situations: Upgrading an old configtx.yaml to V3_0 capabilities (e.g. when moving to BFT) without removing the deprecated Orderer.Addresses section, or copying profiles from Fabric 2.x docs into a V3_0 profile.
Related errors
- orderer type BFT must be used with V3_0 channel capability:
- organization %s not found
- %s capability %s is required but not supported
- cannot enable channel capabilities without orderer support f
- OrdererOrg config does not allow sub-groups
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/f60a7dd2b38c534a.
Report an issue: GitHub.