micro/go-micro · error

message passed in is nil

Error message

message passed in is nil

What it means

httpTransportClient.Recv requires a non-nil *Message to fill with the incoming response body and headers. Passing nil means the caller has nowhere to put the received data, so the transport refuses immediately with 'message passed in is nil'.

Source

Thrown at transport/http_client.go:108

		}
		h.Unlock()
	}

	// set timeout if its greater than 0
	if h.ht.opts.Timeout > time.Duration(0) {
		if err := h.conn.SetDeadline(time.Now().Add(h.ht.opts.Timeout)); err != nil {
			return err
		}
	}

	return req.Write(h.conn)

}

// Recv receives a message.
func (h *httpTransportClient) Recv(msg *Message) (err error) {
	if msg == nil {
		return errors.New("message passed in is nil")
	}

	var req *http.Request

	if !h.dialOpts.Stream {

		var rc *http.Request
		var ok bool

		h.Lock()
		select {
		case rc, ok = <-h.req:
		default:
		}

		if !ok {
			if len(h.reqList) == 0 {
				h.Unlock()

View on GitHub (pinned to 24529f1404)

Solutions

  1. Allocate the message before receiving: msg := &transport.Message{} then client.Recv(msg)
  2. Audit call sites so Recv is never handed a variable that can be nil
  3. If a helper returns the message, check that helper's error/nil return before passing it on

Example fix

// before
var msg *transport.Message
client.Recv(msg) // error: message passed in is nil
// after
msg := &transport.Message{}
if err := client.Recv(msg); err != nil { return err }
Defensive patterns

Strategy: validation

Validate before calling

if msg == nil {
	msg = &transport.Message{}
}
err := client.Recv(msg)

Type guard

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

Try / catch

if err := client.Recv(msg); err != nil {
	if strings.Contains(err.Error(), "message passed in is nil") {
		// fix call site: allocate message
	}
}

Prevention

When it happens

Trigger: Calling client.Recv(nil) directly, or a loop that reuses a msg variable that was never allocated (e.g. var msg *Message declared but not initialized before Recv).

Common situations: Copy-pasted socket code where Recv allocates internally vs client code where the caller must allocate; nil returned from an earlier failed allocation and reused; refactor that dropped the &Message{} initialization.

Related errors


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