nats-io/nats-server · error
eventing shut down
Error message
eventing shut down
What it means
Error returned by fetch/account-lookup when the server's internal eventing (s.sys or its replies map) is already shut down. A lookup request for an account cannot be sent or answered, so the call returns _EMPTY_ account JWT plus this error.
Source
Thrown at server/accounts.go:4732
return res, nil
}
// Caching resolver using nats for lookups and making use of a directory for storage
type CacheDirAccResolver struct {
DirAccResolver
ttl time.Duration
}
func (s *Server) fetch(res AccountResolver, name string, timeout time.Duration) (string, error) {
if s == nil {
return _EMPTY_, ErrNoAccountResolver
}
respC := make(chan []byte, 1)
accountLookupRequest := fmt.Sprintf(accLookupReqSubj, name)
s.mu.Lock()
if s.sys == nil || s.sys.replies == nil {
s.mu.Unlock()
return _EMPTY_, fmt.Errorf("eventing shut down")
}
// Resolver will wait for detected active servers to reply
// before serving an error in case there weren't any found.
expectedServers := len(s.sys.servers)
replySubj := s.newRespInbox()
replies := s.sys.replies
// Store our handler.
replies[replySubj] = func(sub *subscription, _ *client, _ *Account, subject, _ string, msg []byte) {
var clone []byte
isEmpty := len(msg) == 0
if !isEmpty {
clone = make([]byte, len(msg))
copy(clone, msg)
}
s.mu.Lock()
defer s.mu.Unlock()
expectedServers--View on GitHub (pinned to 3a66a489d2)
Solutions
- Retry the account lookup after the server is (re)started and eventing is healthy.
- Treat this as a shutdown signal: stop issuing lookups and drain connections.
- Avoid shutting down the server while account fetches are pending; drain first.
- Check for premature shutdown caused by fatal errors elsewhere in startup.
Example fix
// caller pattern
jwt, err := s.fetchAccount(name)
if err != nil {
if strings.Contains(err.Error(), "eventing shut down") {
return // server shutting down; do not retry now
}
// handle other lookup errors
} Defensive patterns
Strategy: try-catch
Validate before calling
// check eventing before lookup
s.mu.Lock()
up := s.sys != nil && s.sys.replies != nil
s.mu.Unlock()
if !up {
return _EMPTY_, fmt.Errorf("eventing shut down")
} Type guard
func isEventingShutdownErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "eventing shut down")
} Try / catch
jwt, err := s.fetchAccount(name)
if isEventingShutdownErr(err) {
// server is shutting down; abort lookup without retry
return _EMPTY_, err
} Prevention
- Drain clients and stop account fetches before server shutdown.
- Treat this error as terminal during shutdown, not retryable.
- Watch for shutdown races in tests stopping servers with pending lookups.
- Monitor logs for unexpected eventing teardown during normal operation.
When it happens
Trigger: Calling fetchAccount/lookupAccount (e.g. during an account fetch on connect or via resolver lookup) after the server began shutdown and the sys internal client/replies were torn down.
Common situations: Server shutdown races: client connections or account fetches still in flight while s.sys is being closed; tests stopping the server while lookups are pending.
Related errors
- gsl: notification already registered
- error creating store for stream
- error creating store for consumer
- JS_STREAM_OFFLINE
- JS_ERR_GENERIC
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/64c110845bb3c37a.
Report an issue: GitHub.