nats-io/nats-server · error

config reload does not support moving to or from an account

Error message

config reload does not support moving to or from an account resolver

What it means

In nats-server, `gnatsd --signal reload` (or SIGHUP) re-processes the config file and diffs it against the running options. The `accounts` block supports hot reload only if the account resolver configuration stays in place: you cannot add or remove a resolver (the embedded resolver or an external HTTP resolver) at runtime. When the diff detects oldValue==nil XOR newValue==nil for the resolver option, ProcessReloadError returns this error and the whole reload is rejected.

Source

Thrown at server/reload.go:1750

			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.

			// Any deep-equal is likely to fail for when there is a TLSConfig. so
			// remove for the test.
			tmpOld := oldValue.(GatewayOpts)
			tmpNew := newValue.(GatewayOpts)
			tmpOld.TLSConfig = nil
			tmpNew.TLSConfig = nil
			tmpOld.tlsConfigOpts = nil
			tmpNew.tlsConfigOpts = nil

			// Allow TLSPinnedCerts through reload, existing connections

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Restart the server instead of reloading when the presence of the account resolver changes
  2. Make the reload a no-op by keeping the resolver key identical in old and new configs and only changing other account fields
  3. Plan a deliberate restart/migration window to add or remove the resolver

Example fix

// before (config had no resolver, reload adds one)
accounts: { APP: { users: [app] }, resolver: MEMORY }
// after (either keep resolver present on both sides before reloading,
// or restart the server instead of signaling reload)
server # restart, e.g. systemctl restart nats-server
Defensive patterns

Strategy: validation

Validate before calling

// Before signaling reload, compare resolver presence:
func resolverPresenceChanged(old, new *Options) bool {
	return (old.AccountResolver == nil) != (new.AccountResolver == nil)
}
// if resolverPresenceChanged(old, new) { restartInsteadOfReload() }

Type guard

func hasResolver(o *Options) bool { return o != nil && o.AccountResolver != nil }

Prevention

When it happens

Trigger: Sending a reload signal after adding an `resolver: URL` or `resolver: MEMORY` key to the `accounts` block of a config that previously had none, or removing the resolver key (or the accounts resolver TLS config changing presence) from a config that had one.

Common situations: Operators moving a cluster from static account definitions to a JWT/account-resolution setup (or back) by editing the config and issuing SIGHUP; infra-as-code tools that rewrite the accounts block and inadvertently drop or add the resolver field; switching between embedded and HTTP resolvers in a rolling config update.

Related errors


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