OpenNHP/opennhp · error
cluster instance # : invalid port
Error message
cluster %q instance #%d: invalid port %d
What it means
After confirming an instance has an address, buildCluster validates the port. Any Port <= 0 is invalid (Go's config decode may yield 0 when the field is absent), so the cluster cannot form a usable UdpPeer and an error with the cluster name, instance index, and offending port value is returned.
Solutions
- Set a valid positive Port (1-65535, typically 10581 for NHP UDP) on the flagged instance in server.toml.
- Verify the TOML key is exactly Port so it maps to the InstanceConfig field rather than decoding as 0.
- Check the rendered config template output for an empty port placeholder.
- Correct the test/helper (e.g. buildTwoInstanceCluster) if a programmatically built instance forgot the port.
Example fix
// before [[Servers.Instances]] Ip = "10.0.0.5" # Port missing -> decodes as 0 // after [[Servers.Instances]] Ip = "10.0.0.5" Port = 10581
Defensive patterns
Strategy: validation
Validate before calling
if ic.Port <= 0 || ic.Port > 65535 {
return fmt.Errorf("instance %d: port must be 1-65535, got %d", i, ic.Port)
} Try / catch
clusters, err := buildCluster(cfg)
if err != nil {
return fmt.Errorf("invalid server.toml: %w", err)
} Prevention
- Always set Port explicitly on every [[Servers.Instances]] entry.
- Watch for TOML key case mismatches (Port vs port) that decode as 0.
- Validate ports in CI by decoding the TOML and asserting Port > 0.
When it happens
Trigger: buildCluster iterating cfg.Instances and hitting ic.Port <= 0 — typically a [[Servers.Instances]] entry with Port omitted, set to 0, or set to a negative number.
Common situations: Copy-pasting a server.toml block and forgetting the Port line; typo'd TOML key (e.g. port vs Port) so it decodes as 0; envsubst template where the port variable was empty; misreading that ports must be positive (1-65535).
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- cluster instance # : must set either Host or Ip
- relay: server # instance # missing or invalid port
- value is out of range for uint16
- unknown remote provider
- unknown remote provider
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/3e7a079d34aa7bce.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/agent/cluster.go:159
cfg.Name, cfg.PubKeyBase64, err)
}
sc := &ServerCluster{
PublicKeyBase64: cfg.PubKeyBase64,
Name: cfg.Name,
Sticky: cfg.StickyOrDefault(),
instances: make([]*ServerInstance, 0, len(cfg.Instances)),
}
for i, ic := range cfg.Instances {
host := ic.Host
ip := ic.Ip
if host == "" && ip == "" {
return nil, fmt.Errorf("cluster %q instance #%d: must set either Host or Ip",
cfg.Name, i)
}
if ic.Port <= 0 {
return nil, fmt.Errorf("cluster %q instance #%d: invalid port %d",
cfg.Name, i, ic.Port)
}
peer := &core.UdpPeer{
PubKeyBase64: cfg.PubKeyBase64,
Hostname: host,
Ip: ip,
Port: ic.Port,
Type: core.NHP_SERVER,
ExpireTime: cfg.ExpireTime,
}
displayHost := host
if displayHost == "" {
displayHost = ip
}
sc.instances = append(sc.instances, &ServerInstance{
peer: peer,
weight: ic.Weight,
hostPort: fmt.Sprintf("%s:%d", displayHost, ic.Port),View on GitHub (pinned to 6e04ca5ff0)