nats-io/nats-server · error
invalid ClientAdvertise value of %s, err=%v
Error message
invalid ClientAdvertise value of %s, err=%v
What it means
During reload of the client_advertise option, the new string is validated with parseHostPort. An empty value is allowed, but a non-empty value that is not a valid host[:port] makes reload fail with this error.
Source
Thrown at server/reload.go:1740
diffOpts = append(diffOpts, &pidFileOption{newValue: newValue.(string)})
case "portsfiledir":
diffOpts = append(diffOpts, &portsFileDirOption{newValue: newValue.(string), oldValue: oldValue.(string)})
case "maxcontrolline":
diffOpts = append(diffOpts, &maxControlLineOption{newValue: newValue.(int32)})
case "maxpayload":
diffOpts = append(diffOpts, &maxPayloadOption{newValue: newValue.(int32)})
case "pinginterval":
diffOpts = append(diffOpts, &pingIntervalOption{newValue: newValue.(time.Duration)})
case "maxpingsout":
diffOpts = append(diffOpts, &maxPingsOutOption{newValue: newValue.(int)})
case "writedeadline":
diffOpts = append(diffOpts, &writeDeadlineOption{newValue: newValue.(time.Duration)})
case "clientadvertise":
cliAdv := newValue.(string)
if cliAdv != "" {
// Validate ClientAdvertise syntax
if _, _, err := parseHostPort(cliAdv, 0); err != nil {
return nil, fmt.Errorf("invalid ClientAdvertise value of %s, err=%v", cliAdv, err)
}
}
diffOpts = append(diffOpts, &clientAdvertiseOption{newValue: cliAdv})
case "accounts":
diffOpts = append(diffOpts, &accountsOption{})
case "resolver", "accountresolver", "accountsresolver":
// We can't move from no resolver to one. So check for that.
if (oldValue == nil && newValue != nil) ||
(oldValue != nil && newValue == nil) {
return nil, fmt.Errorf("config reload does not support moving to or from an account resolver")
}
diffOpts = append(diffOpts, &accountsOption{})
case "accountresolvertlsconfig":
diffOpts = append(diffOpts, &accountsOption{})
case "gateway":
// Not supported for now, but report warning if configuration of gateway
// is actually changed so that user knows that it won't take effect.
View on GitHub (pinned to 3a66a489d2)
Solutions
- Correct client_advertise to a valid host or host:port (e.g. 'advertise.example.com:4222' or '[::1]:4222').
- Remove the scheme (no 'nats://' or 'http://') and quotes/whitespace from the value.
- Set client_advertise to empty string ("") if you intend to disable advertising, rather than an invalid placeholder.
Example fix
// before client_advertise: "http://node1:4222" // after client_advertise: "node1.example.com:4222"
Defensive patterns
Strategy: validation
Validate before calling
if cliAdv != "" {
if _, _, err := parseHostPort(cliAdv, 0); err != nil {
return fmt.Errorf("invalid client_advertise %q: %v", cliAdv, err)
}
} Try / catch
if err := srv.Reload(); err != nil {
if strings.Contains(err.Error(), "invalid ClientAdvertise") {
log.Printf("fix client_advertise and reload again: %v", err)
}
} Prevention
- Use host or host:port only — no scheme, spaces, or extra colons.
- Bracket IPv6 literals: [::1]:4222.
- Lint config values with a host:port regex before reload.
When it happens
Trigger: Setting client_advertise in the config (or via option reload) to a malformed value like 'my host:99999', 'http://x', or 'host:port:extra' and issuing a reload.
Common situations: Typos in client_advertise (spaces, scheme prefix, invalid port), YAML quoting issues leaving stray whitespace, or IPv6 literals without brackets.
Related errors
- expected 'cert_store' to be a valid non-empty string
- expected 'cert_match_by' to be a valid non-empty string
- expected 'cert_match' to be a valid non-empty string
- jetstream max catchup cannot be negative
- got corrupted escaped character
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/53760cf7275ed4da.
Report an issue: GitHub.