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.EOFView on GitHub (pinned to 24529f1404)
Solutions
- Allocate the message before calling Recv: use m := &transport.Message{Header: map[string]string{}, Body: []byte{}}
- Check for nil before passing: if m == nil { m = &transport.Message{} }
- 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
- Always initialize transport.Message with &transport.Message{} before Recv
- Never declare message vars as nil pointers
- Wrap Recv in a helper that allocates the message internally
- Run go vet / staticcheck to catch obvious nil deref patterns
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
- message passed in is nil
- message passed in is nil
- deadline exceeded
- invalid connection from pool
- addr (nats subject) must not be empty
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/3f8ac11f1d553de0.
Report an issue: GitHub.