micro/go-micro · error

deadline exceeded

Error message

deadline exceeded

What it means

ntportClient.Send publishes to NATS and waits for completion (e.g. flush/ack) up to n.opts.Timeout; if the timer fires first it returns 'deadline exceeded'. This is a client-configured timeout on the send path, not a NATS server error.

Source

Thrown at transport/nats/nats.go:186

	}

	// no deadline
	if n.opts.Timeout == time.Duration(0) {
		return n.conn.PublishRequest(n.addr, n.id, b)
	}

	// use the deadline
	ch := make(chan error, 1)

	go func() {
		ch <- n.conn.PublishRequest(n.addr, n.id, b)
	}()

	select {
	case err := <-ch:
		return err
	case <-time.After(n.opts.Timeout):
		return errors.New("deadline exceeded")
	}
}

func (n *ntportClient) Recv(m *transport.Message) error {
	timeout := time.Second * 10
	if n.opts.Timeout > time.Duration(0) {
		timeout = n.opts.Timeout
	}

	rsp, err := n.sub.NextMsg(timeout)
	if err != nil {
		return err
	}

	var mr transport.Message
	if err := n.opts.Codec.Unmarshal(rsp.Data, &mr); err != nil {
		return err
	}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Increase the Timeout dial/client option to a value suited to your payload size and network latency
  2. Check NATS server health and client connectivity (reconnect logic, servers list) so sends complete quickly
  3. Add retry-with-backoff around Send on this error; consider a longer default or context-aware send for critical messages

Example fix

// before
nats.NewTransport(transport.Timeout(time.Millisecond * 100))
client.Send(m) // deadline exceeded on slow links
// after
nats.NewTransport(transport.Timeout(time.Second * 5))
if err := client.Send(m); err != nil {
	// retry with backoff
	time.Sleep(time.Second)
	err = client.Send(m)
}
Defensive patterns

Strategy: retry

Validate before calling

if timeout < time.Second {
	return errors.New("nats timeout too low for Send")
}

Try / catch

var err error
for i := 0; i < 3; i++ {
	if err = client.Send(m); err == nil || err.Error() != "deadline exceeded" { break }
	time.Sleep(time.Duration(1<<i) * 100 * time.Millisecond)
}

Prevention

When it happens

Trigger: Send on a NATS connection that is slow, blocked, or disconnected so the pending operation doesn't complete within opts.Timeout (default when unset); long-blocking publishes during network partitions.

Common situations: Too-small Timeout option for large payloads or high-latency links; NATS broker unreachable/down so publishes hang until the deadline; closed NATS connection from an idle timeout.

Understand the failure class

Related errors


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