hyperledger/fabric · error

global OrdererAddresses are not allowed with V3_0 capability

Error message

global OrdererAddresses are not allowed with V3_0 capability, use org specific addresses only

What it means

With the V3_0 channel capability enabled, Fabric no longer allows global OrdererAddresses at the channel level; ordering endpoints must be declared per-organization in the orderer group instead. validateNoOrdererAddresses returns this error when a V3_0-capable channel config still contains a non-empty global OrdererAddresses list, because Validate branches to the V3_0 validation path.

Source

Thrown at common/channelconfig/channel.go:228

}

func (cc *ChannelConfig) validateBlockDataHashingStructure() error {
	if cc.protos.BlockDataHashingStructure.Width != math.MaxUint32 {
		return fmt.Errorf("BlockDataHashStructure width only supported at MaxUint32 in this version")
	}
	return nil
}

func (cc *ChannelConfig) validateOrdererAddresses() error {
	if len(cc.protos.OrdererAddresses.Addresses) == 0 {
		return fmt.Errorf("Must set some OrdererAddresses")
	}
	return nil
}

func (cc *ChannelConfig) validateNoOrdererAddresses() error {
	if len(cc.protos.OrdererAddresses.Addresses) > 0 {
		return fmt.Errorf("global OrdererAddresses are not allowed with V3_0 capability, use org specific addresses only")
	}
	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Remove the global OrdererAddresses value from the channel group and set per-organization endpoints under the Orderer group (Orderer: Endpoints / Organizations: Endpoints in configtx.yaml) using configtxgen
  2. Only enable the V3_0 capability after migrating endpoints; or temporarily stay on a pre-V3_0 capability if global addresses are still needed
  3. Decode the current config with configtxlator to locate and delete the OrdererAddresses value, then re-encode and submit the update

Example fix

# before (V3_0)
Channel:
    Capabilities: [V3_0]
    OrdererAddresses:
        - orderer.example.com:7050  # not allowed

# after
Channel:
    Capabilities: [V3_0]
Orderer:
    Endpoints:
        - Host: orderer.example.com
          Port: 7050
          Organization: OrdererOrg
Defensive patterns

Strategy: validation

Validate before calling

func v3Compatible(cfg *cb.Config) error {
    caps := channelCapabilities(cfg) // decode Capabilities value
    if !slices.Contains(caps, "V3_0") { return nil }
    if oa := globalOrdererAddresses(cfg); len(oa) > 0 {
        return errors.New("remove global OrdererAddresses before enabling V3_0")
    }
    return nil
}

Try / catch

cc, err := channelconfig.NewChannelConfig(channelGroup, bccsp)
if err != nil {
    if strings.Contains(err.Error(), "not allowed with V3_0 capability") {
        return fmt.Errorf("migrate to per-org endpoints before enabling V3_0")
    }
    return err
}

Prevention

When it happens

Trigger: A channel whose Capabilities value includes V3_0 runs Validate, which calls validateNoOrdererAddresses; cc.protos.OrdererAddresses.Addresses is non-empty — i.e. upgrading to V3_0 without removing the legacy global OrdererAddresses value.

Common situations: Upgrading a long-running network from v2.x to v3.x: the old config carries global OrdererAddresses that must be migrated to Orderer: Endpoints per organization; configtx.yaml still setting Channel-level OrdererAddresses while Channel capabilities specify V3_0; mixed configtx.yaml versions.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/9d25a41e7fbdd920. Report an issue: GitHub.