micro/go-micro · error

message passed in is nil

Error message

message passed in is nil

What it means

Recv returns this error when the caller passes a nil *transport.Message. The NATS socket implementation requires a non-nil message struct to fill with incoming data; it validates the argument before blocking on the receive channel. This is a caller-side programming bug, not a network problem.

Source

Thrown at transport/nats/nats.go:233

		return n.pool.Put(n.pooledConn)
	}

	// Otherwise, close the connection directly
	n.conn.Close()
	return nil
}

func (n *ntportSocket) Local() string {
	return n.local
}

func (n *ntportSocket) Remote() string {
	return n.remote
}

func (n *ntportSocket) Recv(m *transport.Message) error {
	if m == nil {
		return errors.New("message passed in is nil")
	}

	var r *nats.Msg
	var ok bool

	// if there's a deadline we use it
	if n.opts.Timeout > time.Duration(0) {
		select {
		case r, ok = <-n.r:
		case <-time.After(n.opts.Timeout):
			return errors.New("deadline exceeded")
		}
	} else {
		r, ok = <-n.r
	}

	if !ok {
		return io.EOF

View on GitHub (pinned to 24529f1404)

Solutions

  1. Allocate the message before calling Recv: use m := &transport.Message{Header: map[string]string{}, Body: []byte{}}
  2. Check for nil before passing: if m == nil { m = &transport.Message{} }
  3. Audit code paths that construct the message to ensure none return nil

Example fix

// before
var msg *transport.Message
if err := sock.Recv(msg); err != nil { ... }
// after
msg := &transport.Message{Header: map[string]string{}}
if err := sock.Recv(msg); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

func ensureMsg(m *transport.Message) *transport.Message {
	if m == nil {
		return &transport.Message{Header: map[string]string{}}
	}
	return m
}
// if err := sock.Recv(ensureMsg(msg)); err != nil { ... }

Type guard

func isNilMessage(m *transport.Message) bool { return m == nil }

Try / catch

if err := sock.Recv(msg); err != nil {
	if err.Error() == "message passed in is nil" {
		return fmt.Errorf("recv: message must be allocated: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling socket.Recv(nil) on an *ntportSocket obtained from a NATS transport listener or client, e.g. reusing a message variable that was never initialized with &transport.Message{Header: ..., Body: ...}.

Common situations: Declarations like `var msg *transport.Message` instead of `msg := &transport.Message{}`; a helper returning nil on some code path; refactoring that removed the allocation but left the Recv call.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/3f8ac11f1d553de0. Report an issue: GitHub.