micro/go-micro · error

channel closed before could receive confirmation of publish

Error message

channel closed before could receive confirmation of publish

What it means

When publisher confirms are enabled, Publish waits on the r.confirmPublish channel for the broker's ack. If that channel is closed (ok == false), the AMQP channel died before the confirmation arrived, so Publish returns this error — the message's delivery outcome is unknown.

Source

Thrown at broker/rabbitmq/channel.go:87

func (r *rabbitMQChannel) Publish(exchange, key string, message amqp.Publishing) error {
	if r.channel == nil {
		return errors.New("channel is nil")
	}

	if r.confirmPublish != nil {
		r.mtx.Lock()
		defer r.mtx.Unlock()
	}

	err := r.channel.Publish(exchange, key, false, false, message)
	if err != nil {
		return err
	}

	if r.confirmPublish != nil {
		confirmation, ok := <-r.confirmPublish
		if !ok {
			return errors.New("channel closed before could receive confirmation of publish")
		}

		if !confirmation.Ack {
			return errors.New("could not publish message, received nack from broker on confirmation")
		}
	}

	return nil
}

func (r *rabbitMQChannel) DeclareExchange(ex Exchange) error {
	return r.channel.ExchangeDeclare(
		ex.Name,         // name
		string(ex.Type), // kind
		ex.Durable,      // durable
		false,           // autoDelete
		false,           // internal
		false,           // noWait

View on GitHub (pinned to 24529f1404)

Solutions

  1. Treat the message as undelivered-or-delivered (ambiguous): retry with an idempotency key if exactly-once semantics matter.
  2. Enable automatic reconnect and re-open the channel, then republish.
  3. Check RabbitMQ server logs for why the channel was closed at that moment.

Example fix

// before
if err := ch.Publish(ex, key, msg); err != nil { return err }
// after
if err := ch.Publish(ex, key, msg); err != nil {
    if strings.Contains(err.Error(), "closed before could receive confirmation") {
        return idempotentRepublish(ex, key, msg) // safe retry with dedupe key
    }
    return err
}
Defensive patterns

Strategy: retry

Try / catch

if err := ch.Publish(ex, key, msg); err != nil {
    if strings.Contains(err.Error(), "closed before could receive confirmation") {
        reconnect(); return idempotentRepublish(ex, key, msg)
    }
    return err
}

Prevention

When it happens

Trigger: RabbitMQ channel/connection closes (network drop, server restart, forced channel close by broker) between sending the publish and receiving the confirm; reading from a closed confirm channel.

Common situations: Network interruptions or RabbitMQ node failover during high-volume publish bursts; broker closing channels due to internal errors (e.g. pressure) while confirms are pending.

Related errors


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