nats-io/nats-server · error

leafnodes disabled

Error message

leafnodes disabled

What it means

ErrLeafNodeDisabled is returned by connectToRemoteLeafNode when the server's leaf-node outbound connections are disabled (s.isLeafConnectDisabled()). The server logs that it will not attempt to connect to the configured remote and aborts the solicitation with this error instead of dialing.

Source

Thrown at server/errors.go:94

	ErrTooManySubs = errors.New("maximum subscriptions exceeded")

	// ErrTooManySubTokens signals a client that the subject has too many tokens.
	ErrTooManySubTokens = errors.New("subject has exceeded number of tokens limit")

	// ErrClientConnectedToRoutePort represents an error condition when a client
	// attempted to connect to the route listen port.
	ErrClientConnectedToRoutePort = errors.New("attempted to connect to route port")

	// ErrClientConnectedToLeafNodePort represents an error condition when a client
	// attempted to connect to the leaf node listen port.
	ErrClientConnectedToLeafNodePort = errors.New("attempted to connect to leaf node port")

	// ErrLeafNodeHasSameClusterName represents an error condition when a leafnode is a cluster
	// and it has the same cluster name as the hub cluster.
	ErrLeafNodeHasSameClusterName = errors.New("remote leafnode has same cluster name")

	// ErrLeafNodeDisabled is when we disable leafnodes.
	ErrLeafNodeDisabled = errors.New("leafnodes disabled")

	// ErrConnectedToWrongPort represents an error condition when a connection is attempted
	// to the wrong listen port (for instance a LeafNode to a client port, etc...)
	ErrConnectedToWrongPort = errors.New("attempted to connect to wrong port")

	// ErrAccountExists is returned when an account is attempted to be registered
	// but already exists.
	ErrAccountExists = errors.New("account exists")

	// ErrBadAccount represents a malformed or incorrect account.
	ErrBadAccount = errors.New("bad account")

	// ErrReservedAccount represents a reserved account that can not be created.
	ErrReservedAccount = errors.New("reserved account")

	// ErrMissingAccount is returned when an account does not exist.
	ErrMissingAccount = errors.New("account missing")

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Remove the disable-leafnodes option/flag so the server may solicit remote leaf connections
  2. Remove the leafnodes remotes entries from config if leaf links are genuinely unwanted
  3. Restart/reload the server after changing the option

Example fix

// before
srv, _ := server.NewServer(opts)
opts.NoLeafNode = true // connect disabled
// after
opts.NoLeafNode = false
srv, _ := server.NewServer(opts)
go srv.Start()
Defensive patterns

Strategy: validation

Validate before calling

if serverDisabledLeafConnect(opts) && len(opts.LeafNode.Remotes) > 0 {
    return fmt.Errorf("leaf remotes configured but leaf connections are disabled")
}

Try / catch

if err := srv.ConnectRemotes(); err != nil && errors.Is(err, ErrLeafNodeDisabled) {
    log.Printf("leaf connect disabled: skipping remote %s", url)
}

Prevention

When it happens

Trigger: Calling the leaf-node connect path (e.g. via server.Start or Reload triggering remote leaf solicitation) while the server option to disable leafnode connections is set (e.g. leafnodes disabled via config/option -noleaf or NoLeafNode style flag). Seen at leafnode.go:797.

Common situations: Operators hardening a server (edge node) with leaf connect disabled but leftover leafnodes remotes config; CI environments starting servers with disable flags; tests or tooling expecting leaf links that were disabled at startup.

Related errors


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