nats-io/nats-server · error

undefined message handler

Error message

undefined message handler

What it means

Returned by the server's internal system request helper when it is invoked with a nil message handler callback while events (system account) are enabled. The library requires a callback to deliver the response of a system request it issues on the caller's behalf.

Source

Thrown at server/events.go:2867

// Create an internal subscription with queue
func (s *Server) sysSubscribeQ(subject, queue string, cb msgHandler) (*subscription, error) {
	return s.systemSubscribe(subject, queue, false, nil, cb)
}

// Create an internal subscription but do not forward interest.
func (s *Server) sysSubscribeInternal(subject string, cb msgHandler) (*subscription, error) {
	return s.systemSubscribe(subject, _EMPTY_, true, nil, cb)
}

func (s *Server) systemSubscribe(subject, queue string, internalOnly bool, c *client, cb msgHandler) (*subscription, error) {
	s.mu.Lock()
	if !s.eventsEnabled() {
		s.mu.Unlock()
		return nil, ErrNoSysAccount
	}
	if cb == nil {
		s.mu.Unlock()
		return nil, fmt.Errorf("undefined message handler")
	}
	if c == nil {
		c = s.sys.client
	}
	trace := c.trace
	s.sys.sid++
	sid := strconv.Itoa(s.sys.sid)
	s.mu.Unlock()

	// Now create the subscription
	if trace {
		c.traceInOp("SUB", []byte(subject+" "+queue+" "+sid))
	}

	var q []byte
	if queue != _EMPTY_ {
		q = []byte(queue)
	}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Provide a non-nil msgHandler callback when issuing the internal system request
  2. Check that events are enabled (eventsEnabled) and system account configured before calling
  3. If a no-op response is acceptable, pass an empty handler function instead of nil

Example fix

// before
resp, err := s.requestResponse(subj, nil, nil)
// after
resp, err := s.requestResponse(subj, nil, func(_ *subscription, _ *client, _ *Account, _ string, _ string, hdr, msg []byte) {})
Defensive patterns

Strategy: validation

Validate before calling

if cb == nil {
    return errors.New("system request requires a message handler")
}

Type guard

func handlerProvided(cb sysMsgHandler) bool { return cb != nil }

Try / catch

resp, err := s.requestSystemRequest(subj, cb)
if err != nil {
    if err.Error() == "undefined message handler" {
        // supply a callback and retry
    }
    return err
}

Prevention

When it happens

Trigger: Calling the internal requestSystemRequest/helper (e.g. s.newResp or equivalent system-request wrapper) with cb == nil while passing a subject to request system info.

Common situations: Plugin or forked-server code invoking the server's internal system request API without supplying a handler; refactoring that dropped a callback argument.

Related errors


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