OpenNHP/opennhp · error
: [[Servers]][ ] ( ) missing Name — clusters are referenced…
Error message
%s: [[Servers]][%d] (%s) missing Name — clusters are referenced from resource.toml by Name
What it means
When opts.RequireName is set, Normalize additionally demands a non-empty Name per cluster, because clusters are referenced from resource.toml by Name rather than by key or index. An anonymous cluster cannot be referenced and is rejected, with the entry's key echoed for identification.
Solutions
- Add a unique Name to every [[Servers]] block in the cluster config
- Use the same Name string in resource.toml cluster references so lookups resolve
- Keep each Name within NameMaxLen — check the surrounding validation for the length limit
- Update config templates so future deployments always emit Name alongside PubKeyBase64
Example fix
// before (server.toml) [[Servers]] PubKeyBase64 = "<key>" // after [[Servers]] Name = "nhp-server-1" PubKeyBase64 = "<key>"
Defensive patterns
Strategy: validation
Validate before calling
for i, c := range clusters {
if c.Name == "" {
return fmt.Errorf("cluster %d needs a Name (referenced from resource.toml)", i)
}
}
err := clusterconfig.Normalize(clusters, clusterconfig.NormalizeOptions{RequireName: true, ...}) Try / catch
if err := clusterconfig.Normalize(clusters, opts); err != nil {
if strings.Contains(err.Error(), "missing Name") {
return fmt.Errorf("multi-cluster configs require per-cluster Name fields: %w", err)
}
return err
} Prevention
- Mandate Name in every [[Servers]] block even for single-cluster setups
- Keep a mapping check in CI: every cluster Name referenced by resource.toml exists in server.toml
- Update config templates when migrating from the single-cluster demo format
When it happens
Trigger: Calling Normalize with RequireName=true (e.g. from normalizeClusters for multi-cluster deployments) and clusters[i].Name == "".
Common situations: Upgrading from a single-cluster config where Name was optional to the multi-cluster format that requires it; docker-compose demo configs copied without adding Name; resource.toml referencing clusters by Name while server.toml entries lack the field.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- server peer config invalid on initial load
- config load error
- relay: failed to parse config
- : no [[Servers]] configured
- : [[Servers]][ ] missing PubKeyBase64
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/7f6a945be69e415a.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/common/clusterconfig/clusterconfig.go:151
}
label := opts.ConsumerLabel
if label == "" {
label = "cluster"
}
if len(clusters) == 0 {
return fmt.Errorf("%s: no [[Servers]] configured", label)
}
for i, c := range clusters {
if c == nil {
return fmt.Errorf("%s: [[Servers]][%d] is nil", label, i)
}
if c.PubKeyBase64 == "" {
return fmt.Errorf("%s: [[Servers]][%d] missing PubKeyBase64", label, i)
}
if opts.RequireName {
if c.Name == "" {
return fmt.Errorf("%s: [[Servers]][%d] (%s) missing Name — clusters are referenced from resource.toml by Name",
label, i, c.PubKeyBase64)
}
if len(c.Name) > NameMaxLen {
return fmt.Errorf("%s: [[Servers]][%d] Name %q exceeds %d chars",
label, i, c.Name, NameMaxLen)
}
if !clusterNameRegex.MatchString(c.Name) {
return fmt.Errorf("%s: [[Servers]][%d] Name %q invalid — allowed chars: [a-zA-Z0-9._-]",
label, i, c.Name)
}
}
legacy := c.hasLegacyFields()
hasInstances := len(c.Instances) > 0
switch {
case legacy && hasInstances:
// Both forms in one entry is almost certainly anView on GitHub (pinned to 6e04ca5ff0)