{"record":{"id":"f60a7dd2b38c534a","repo":"hyperledger/fabric","slug":"global-orderer-endpoints-exist-but-can-not-be-use","errorCode":null,"errorMessage":"global orderer endpoints exist, but can not be used with V3_0 capability: %v","messagePattern":"global orderer endpoints exist, but can not be used with V3_0 capability: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configtxgen/encoder/encoder.go","lineNumber":190,"sourceCode":"\t\tchannelGroup.Groups[channelconfig.ConsortiumsGroupKey], err = NewConsortiumsGroup(conf.Consortiums)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"could not create consortiums group\")\n\t\t}\n\t}\n\n\tchannelGroup.ModPolicy = channelconfig.AdminsPolicyKey\n\treturn channelGroup, nil\n}\n\n// NewOrdererGroup returns the orderer component of the channel configuration.  It defines parameters of the ordering service\n// about how large blocks should be, how frequently they should be emitted, etc. as well as the organizations of the ordering network.\n// It sets the mod_policy of all elements to \"Admins\".  This group is always present in any channel configuration.\nfunc NewOrdererGroup(conf *genesisconfig.Orderer, channelCapabilities map[string]bool) (*cb.ConfigGroup, error) {\n\tif conf.OrdererType == \"BFT\" && !channelCapabilities[\"V3_0\"] {\n\t\treturn nil, errors.Errorf(\"orderer type BFT must be used with V3_0 channel capability: %v\", channelCapabilities)\n\t}\n\tif len(conf.Addresses) > 0 && channelCapabilities[\"V3_0\"] {\n\t\treturn nil, errors.Errorf(\"global orderer endpoints exist, but can not be used with V3_0 capability: %v\", conf.Addresses)\n\t}\n\n\tordererGroup := protoutil.NewConfigGroup()\n\tif err := AddOrdererPolicies(ordererGroup, conf.Policies, channelconfig.AdminsPolicyKey); err != nil {\n\t\treturn nil, errors.Wrapf(err, \"error adding policies to orderer group\")\n\t}\n\taddValue(ordererGroup, channelconfig.BatchSizeValue(\n\t\tconf.BatchSize.MaxMessageCount,\n\t\tconf.BatchSize.AbsoluteMaxBytes,\n\t\tconf.BatchSize.PreferredMaxBytes,\n\t), channelconfig.AdminsPolicyKey)\n\taddValue(ordererGroup, channelconfig.BatchTimeoutValue(conf.BatchTimeout.String()), channelconfig.AdminsPolicyKey)\n\taddValue(ordererGroup, channelconfig.ChannelRestrictionsValue(conf.MaxChannels), channelconfig.AdminsPolicyKey)\n\n\tif len(conf.Capabilities) > 0 {\n\t\taddValue(ordererGroup, channelconfig.CapabilitiesValue(conf.Capabilities), channelconfig.AdminsPolicyKey)\n\t}\n","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/configtxgen/encoder/encoder.go#L172-L208","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nOrderer:\n    OrdererType: etcdraft\n    Addresses:\n        - orderer.example.com:7050\n# after\nOrderer:\n    OrdererType: etcdraft\n    # Addresses removed for V3_0; endpoints come from consenter config\n    EtcdRaft:\n        Consenters:\n            - Host: orderer.example.com\n              Port: 7050","handlingStrategy":"validation","validationCode":"func validateNoGlobalAddresses(conf *genesisconfig.Orderer, caps map[string]bool) error {\n    if len(conf.Addresses) > 0 && caps[\"V3_0\"] {\n        return fmt.Errorf(\"remove Orderer.Addresses %v when V3_0 capability is enabled\", conf.Addresses)\n    }\n    return nil\n}","typeGuard":"func hasGlobalOrdererAddresses(conf *genesisconfig.Orderer) bool { return len(conf.Addresses) > 0 }","tryCatchPattern":"group, err := encoder.NewOrdererGroup(conf, caps)\nif err != nil && strings.Contains(err.Error(), \"global orderer endpoints\") {\n    return fmt.Errorf(\"delete the Addresses: section under Orderer in configtx.yaml for V3_0: %w\", err)\n}","preventionTips":["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"],"tags":["config","hyperledger-fabric","capabilities","orderer"],"backgroundTag":"channel-capability-mismatch","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}