nats-io/nats-server · error
remote %s: %s
Error message
remote %s: %s
What it means
While diffing leaf node remotes during reload, checkConfigsEqual on a leaf remote (leafnodes.remotes[i]) returned an unsupported field change (TLSHandshakeFirst, TLSConfig, etc. are in the ignore list but the rest failed). The error is wrapped as remote <name>: <cause>.
Source
Thrown at server/reload.go:999
if rlo == nil {
// Not found, will be removed in leafNodeOption.Apply().
removed = true
lrc.RUnlock()
continue
}
// Now we need to make sure that there are no changes that we don't
// support for a RemoteLeafOpts.
err := checkConfigsEqual(lrc.RemoteLeafOpts, rlo, []string{
"Compression",
"Disabled",
"TLS",
"TLSHandshakeFirst",
"TLSConfig",
})
if err != nil {
lrc.RUnlock()
s.mu.RUnlock()
return nil, fmt.Errorf(remoteErrFormat, rlo.safeName(), err)
}
disabledChanged := lrc.Disabled != rlo.Disabled
// If this remote was disabled and is now enabled, we need to make sure
// that there is no connect in progress. If that is the case, either
// try again (if it is the first failure) or return an error.
if disabledChanged && lrc.Disabled && lrc.connInProgress {
lrc.RUnlock()
s.mu.RUnlock()
if failed < maxAttempts-1 {
continue forLoop
}
return nil, fmt.Errorf(remoteErrFormat, rlo.safeName(),
"cannot be enabled at the moment, try again")
}
// Since we will use the new `rlo.TLSConfig` later on, consider all
// existing remote configs as "changed" and store them in the
// `nlo.changed` map.
if nlo.changed == nil {View on GitHub (pinned to 3a66a489d2)
Solutions
- Revert the unsupported remote field in the config, or restart the server to apply it.
- Restrict reload edits to supported remote fields (check NATS reload docs for the allow-list).
- Split changes: reload supported fields now; schedule a restart for the remote connection changes.
Example fix
// before (reload)
leafnodes { remotes: [ { url: "nats://other:4222", credentials: "new.creds" } ] }
// after
leafnodes { remotes: [ { url: "nats://other:4222", credentials: "old.creds" } ] } // restart to swap creds Defensive patterns
Strategy: validation
Validate before calling
// pre-validate that only hot-reloadable leaf remote fields changed
unsupported := []string{"credentials", "tls", "urls"}
for _, f := range unsupported {
if remoteChanged(oldRemote, newRemote, f) {
return fmt.Errorf("field %q of leaf remote requires restart", f)
}
} Try / catch
if err := srv.Reload(); err != nil {
if strings.HasPrefix(err.Error(), "remote ") {
log.Printf("leaf remote reload rejected, restart needed: %v", err)
}
} Prevention
- Consult the NATS reload documentation allow-list before editing leaf remotes live.
- Rotate leaf remote credentials via restarts in maintenance windows.
- Version-control configs and diff before reload.
When it happens
Trigger: Editing a field of an existing leafnodes.remotes[] entry that cannot be hot-reloaded (e.g. credentials, urls, TLS details) and calling Reload() or sending SIGHUP.
Common situations: Rotating leaf remote credentials or URLs via reload; adding/removing accounts in a remote entry; changing TLS material of a running remote connection.
Related errors
- field "Users": old=%v, new=%v
- remote %s: cannot be added at the moment, try again
- OnReload, sort or explicitly skip type: %s
- unable to add account %q to the list of dedicated routes: %v
- invalid ClientAdvertise value of %s, err=%v
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/f04ebea28a41adf1.
Report an issue: GitHub.