hyperledger/fabric · error

%s is not a valid port number

Error message

%s is not a valid port number

What it means

This error means the port portion of a global orderer endpoint parsed by net.SplitHostPort is not a valid integer in the int32 range, so it cannot be converted to the uint32 port of a discovery.Endpoint. Like the parse failure of the full endpoint, this aborts the entire globalEndpoints computation. The message contains the offending port substring.

Source

Thrown at discovery/support/config/support.go:192

		}
	}

	return res, nil
}

func globalEndpoints(endpointsByMSPID map[string][]string, ordererAddresses []string) (map[string]*discovery.Endpoints, error) {
	res := make(map[string]*discovery.Endpoints)

	for mspID := range endpointsByMSPID {
		res[mspID] = &discovery.Endpoints{}
		for _, endpoint := range ordererAddresses {
			host, portStr, err := net.SplitHostPort(endpoint)
			if err != nil {
				return nil, errors.Errorf("failed parsing orderer endpoint %s", endpoint)
			}
			port, err := strconv.ParseInt(portStr, 10, 32)
			if err != nil {
				return nil, errors.Errorf("%s is not a valid port number", portStr)
			}
			res[mspID].Endpoint = append(res[mspID].Endpoint, &discovery.Endpoint{
				Host: host,
				Port: uint32(port),
			})
		}
	}
	return res, nil
}

func appendMSPConfigs(ordererGrp, appGrp map[string]*common.ConfigGroup, output map[string]*msp.FabricMSPConfig) error {
	for _, group := range []map[string]*common.ConfigGroup{ordererGrp, appGrp} {
		for _, grp := range group {
			mspConfig := &msp.MSPConfig{}
			if err := proto.Unmarshal(grp.Values[channelconfig.MSPKey].Value, mspConfig); err != nil {
				return errors.Wrap(err, "failed parsing MSPConfig")
			}
			// Skip non fabric MSPs, as they don't carry useful information for service discovery

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Replace the non-numeric or out-of-range port with a valid numeric port (1-65535) in the orderer addresses.
  2. Regenerate/update the channel configuration via configtxgen/configtxlator after fixing.
  3. Pre-validate endpoints by splitting and parsing the port before config submission.
  4. Check for unresolved template/env placeholders or truncated ':' values in the config source.

Example fix

// before
OrdererAddresses:
  - orderer.example.com:grpc
// after
OrdererAddresses:
  - orderer.example.com:7050
Defensive patterns

Strategy: validation

Validate before calling

func validatePorts(addrs []string) error {
    for _, a := range addrs {
        _, portStr, err := net.SplitHostPort(a)
        if err != nil {
            return err
        }
        if _, err := strconv.ParseInt(portStr, 10, 32); err != nil {
            return fmt.Errorf("address %q has invalid port %q", a, portStr)
        }
    }
    return nil
}

Type guard

func hasValidPort(s string) bool {
    _, portStr, err := net.SplitHostPort(s)
    if err != nil {
        return false
    }
    p, err := strconv.ParseInt(portStr, 10, 32)
    return err == nil && p > 0 && p <= 65535
}

Try / catch

eps, err := support.OrdererEndpoints()
if err != nil {
    if strings.Contains(err.Error(), "not a valid port number") {
        // surface a config-validation message pointing at the offending port
    }
    return err
}

Prevention

When it happens

Trigger: In globalEndpoints, after a successful host:port split, strconv.ParseInt(portStr, 10, 32) fails because portStr is non-numeric (e.g. 'orderer.example.com:http', '7o50'), empty (address ended with ':'), or numerically out of range.

Common situations: Named service ports ('orderer:grpc') instead of numeric ports in OrdererAddresses; truncated addresses like 'host:'; typos in configtx.yaml; template variables not substituted leaving placeholders in the port position.

Related errors


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