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

  1. Ensure broker.Connect(context) is called and succeeded before any Publish.
  2. Configure NATS reconnect options (nats.MaxReconnects, retry on failed connect) so transient outages restore n.conn automatically.
  3. On this error, check connectivity to the NATS server (host/port, credentials) and re-run Connect().
  4. 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

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


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