micro/go-micro · error
not connected
Error message
not connected
What it means
In non-pooled mode the NATS broker publishes through its single stored connection `n.conn`. If that field is nil, there is no active NATS connection, so Publish returns this error. It is the classic 'publish before connect' or 'connection lost' signal for the single-connection path.
Source
Thrown at broker/nats/nats.go:247
// Use connection pool if enabled
if n.pool != nil {
poolConn, err := n.pool.Get()
if err != nil {
return err
}
defer func() { _ = n.pool.Put(poolConn) }()
conn := poolConn.Conn()
if conn == nil {
return errors.New("invalid connection from pool")
}
return conn.Publish(topic, b)
}
// Use single connection (original behavior)
if n.conn == nil {
return errors.New("not connected")
}
return n.conn.Publish(topic, b)
}
func (n *natsBroker) Subscribe(topic string, handler broker.Handler, opts ...broker.SubscribeOption) (broker.Subscriber, error) {
n.RLock()
hasConnection := n.conn != nil || n.pool != nil
n.RUnlock()
if !hasConnection {
return nil, errors.New("not connected")
}
opt := broker.SubscribeOptions{
AutoAck: true,
Context: context.Background(),
}View on GitHub (pinned to 24529f1404)
Solutions
- Ensure broker.Connect(context) is called and succeeded before any Publish.
- Configure NATS reconnect options (nats.MaxReconnects, retry on failed connect) so transient outages restore n.conn automatically.
- On this error, check connectivity to the NATS server (host/port, credentials) and re-run Connect().
- Verify no code path calls Disconnect() while publishers are still active.
Example fix
// before
b := nats.NewBroker(broker.Addrs(addr))
_ = b.Publish(ctx, "events", msg) // panics into 'not connected'
// after
b := nats.NewBroker(broker.Addrs(addr))
if err := b.Connect(ctx); err != nil {
log.Fatal(err)
}
if err := b.Publish(ctx, "events", msg); err != nil {
log.Fatal(err)
} Defensive patterns
Strategy: retry
Validate before calling
if err := br.Connect(ctx); err != nil {
return fmt.Errorf("broker connect failed: %w", err)
}
// safe to Publish now Type guard
func isNotConnected(err error) bool {
return err != nil && strings.Contains(err.Error(), "not connected")
} Try / catch
if err := br.Publish(ctx, topic, msg); err != nil {
if strings.Contains(err.Error(), "not connected") {
_ = br.Connect(ctx) // or reconnect with backoff
err = br.Publish(ctx, topic, msg)
}
return err
} Prevention
- Always pair nats.NewBroker with a checked Connect() call at startup.
- Enable NATS client reconnect options (nats.MaxReconnects(-1), RetryOnFailedConnect) to survive server restarts.
- Health-check the broker before publishing in long-running loops.
- Gate Disconnect() behind application shutdown so publishers are finished first.
When it happens
Trigger: Calling Publish on a natsBroker when n.conn == nil — i.e., before Connect() succeeds, after Disconnect()/Close(), or if the client connection was lost and never re-established (broker/nats/nats.go:247).
Common situations: Publishing before Connect() in application startup; NATS server outage causing a permanently closed connection when reconnect options are exhausted; tests that forget to connect a shared broker fixture.
Related errors
- invalid connection from pool
- agent: StreamAsk unsupported by implementation
- agent: ResumeStreamAsk unsupported by implementation
- agent: ResumeStreamAsk requires a checkpoint
- agent: checkpointed run not found
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/ba55c7754427219b.
Report an issue: GitHub.