nats-io/nats-server · error

config reload not supported for %s: old=%v, new=%v

Error message

config reload not supported for %s: old=%v, new=%v

What it means

The `gateway` block of a nats-server config is only partially reloadable. ProcessReload copies old and new GatewayOpts, strips remote-gateway TLS configs, and if any remaining field still differs (addresses, ports, names, remotes, etc.) it rejects the reload with this error, including the field name and both values in the message.

Source

Thrown at server/reload.go:1782

			tmpNew.TLSConfig = nil
			tmpOld.tlsConfigOpts = nil
			tmpNew.tlsConfigOpts = nil

			// Allow TLSPinnedCerts through reload, existing connections
			// are checked in recheckPinnedCerts
			tmpOld.TLSPinnedCerts = nil
			tmpNew.TLSPinnedCerts = nil

			// Need to do the same for remote gateways' TLS configs.
			// But we can't just set remotes' TLSConfig to nil otherwise this
			// would lose the real TLS configuration.
			tmpOld.Gateways = copyRemoteGWConfigsWithoutTLSConfig(tmpOld.Gateways)
			tmpNew.Gateways = copyRemoteGWConfigsWithoutTLSConfig(tmpNew.Gateways)

			// If there is really a change prevents reload.
			if !reflect.DeepEqual(tmpOld, tmpNew) {
				// See TODO(ik) note below about printing old/new values.
				return nil, fmt.Errorf("config reload not supported for %s: old=%v, new=%v",
					field.Name, oldValue, newValue)
			}
		case "leafnode":
			tmpOld := oldValue.(LeafNodeOpts)
			tmpNew := newValue.(LeafNodeOpts)

			lno, err := getLeafNodeOptionsChanges(s, &tmpOld, &tmpNew)
			// If there was an unsupported change, we will get an error with the name
			// of the (first) field and its old and new value.
			if err != nil {
				return nil, fmt.Errorf("config reload not supported for %s: %v", field.Name, err)
			}
			// If there was an actual change...
			if lno != nil {
				diffOpts = append(diffOpts, lno)
			}
		case "jetstream":
			new := newValue.(bool)

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Restrict gateway config changes to TLS certificate/key paths, which reload does support
  2. Restart the server for any other gateway topology change
  3. Fix the config so old and new gateway blocks are identical, then reload

Example fix

// before
server # nats-server -sl reload=pid  (after changing gateways: remotes)
// after
server # systemctl restart nats-server  (topology changes need restart)
Defensive patterns

Strategy: validation

Validate before calling

// Only TLS cert/key paths may differ for gateways on reload:
func gatewayReloadSafe(old, new GatewayOpts) bool {
	o, n := old, new
	o.TLSConfig, o.tlsConfigOpts = nil, nil
	n.TLSConfig, n.tlsConfigOpts = nil, nil
	for i := range o.Gateways { o.Gateways[i].TLSConfig = nil }
	for i := range n.Gateways { n.Gateways[i].TLSConfig = nil }
	return reflect.DeepEqual(o, n)
}

Try / catch

if err := s.Reload(); err != nil {
	if strings.Contains(err.Error(), "config reload not supported for gateway") {
		log.Fatalf("gateway change requires restart: %v", err)
	}
	panic(err)
}

Prevention

When it happens

Trigger: Signaling reload after changing any gateway option that is not TLS-certificate related — e.g. `gateways.name`, `gateways.port`, `gateways.urls`, `gateways.advertise`, the list of remote gateways, or adding/removing the whole gateways block.

Common situations: Fleet config tools rewriting the gateways section (adding a new remote cluster) and triggering SIGHUP; fixing a mistyped gateway URL or port at runtime; rotating gateway credentials other than the TLS cert/key pair.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/a9e72212432ed92f. Report an issue: GitHub.