nats-io/nats-server · error
leaf nodes and gateways (both being defined) require a syste
Error message
leaf nodes and gateways (both being defined) require a system account to also be configured
What it means
When both leaf nodes and a gateway are configured, the server requires a system account so that cluster/supercluster control messages have an account to run under. validateLeafNode throws this during Options validation when Options defines leaf node connections and a gateway (name or port) but Options.SystemAccount is empty. Without it, routing of system-level interest between leaf nodes and gateways cannot work correctly.
Source
Thrown at server/leafnode.go:349
// If MinVersion is defined, check that it is valid.
if mv := o.LeafNode.MinVersion; mv != _EMPTY_ {
if err := checkLeafMinVersionConfig(mv); err != nil {
return err
}
}
// The checks below will be done only when detecting that we are configured
// with gateways. So if an option validation needs to be done regardless,
// it MUST be done before this point!
if o.Gateway.Name == _EMPTY_ && o.Gateway.Port == 0 {
return nil
}
// If we are here we have both leaf nodes and gateways defined, make sure there
// is a system account defined.
if o.SystemAccount == _EMPTY_ {
return fmt.Errorf("leaf nodes and gateways (both being defined) require a system account to also be configured")
}
if err := validatePinnedCerts(o.LeafNode.TLSPinnedCerts); err != nil {
return fmt.Errorf("leafnode: %v", err)
}
return nil
}
func checkLeafMinVersionConfig(mv string) error {
if ok, err := versionAtLeastCheckError(mv, 2, 8, 0); !ok || err != nil {
if err != nil {
return fmt.Errorf("invalid leafnode's minimum version: %v", err)
} else {
return fmt.Errorf("the minimum version should be at least 2.8.0")
}
}
return nil
}
View on GitHub (pinned to 3a66a489d2)
Solutions
- Add a system account to the config, e.g. accounts { SYS { ... } } and system_account = "SYS-internal-nkey"
- Generate an account NKEY with nsc and set it as system_account in Options
- If gateways are not actually needed, remove the gateway name/port configuration
Example fix
// before
leafnodes { ... }
gateway { name: "A", port: 7222 }
// after
accounts { SYS { users: [ { nkey: "AB..." } ] } }
system_account: "AB..."
leafnodes { ... }
gateway { name: "A", port: 7222 } Defensive patterns
Strategy: validation
Validate before calling
if (opts.LeafNode != nil && hasLeafRemotes(opts)) &&
(opts.Gateway.Name != "" || opts.Gateway.Port != 0) &&
opts.SystemAccount == "" {
return errors.New("leafnodes + gateway require a system account")
} Prevention
- Always define a system account in clustered/leaf topologies
- Run `nats-server -t` in CI on every config change
- Use a shared config template that includes accounts.SYS and system_account
When it happens
Trigger: Calling server.NewServer(opts) / opts.Validate() (via validateOptions -> validateLeafNode) where o.LeafNode is configured AND (o.Gateway.Name != "" or o.Gateway.Port != 0) AND o.SystemAccount == "".
Common situations: Operators add a gateway block to an existing config that only had leaf nodes (or vice versa) and forget the accounts.system_account setting; templates copied from simple leaf-node examples then extended with clustering.
Related errors
- gateway name cannot contain spaces
- system_account in config and operator JWT must be identical
- remote leaf node URL %q cannot be used in FIPS-140 mode when
- leafnode: %v
- invalid leafnode's minimum version: %v
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/a6d76451425aa324.
Report an issue: GitHub.