micro/go-micro · error
could not publish message, received nack from broker on conf
Error message
could not publish message, received nack from broker on confirmation
What it means
With publisher confirms enabled, after receiving a confirmation Publish checks confirmation.Ack. If the broker sent a nack, the message was rejected/not persisted by RabbitMQ, and this error is returned. Unlike the closed-channel case, the broker explicitly said the message was not accepted.
Source
Thrown at broker/rabbitmq/channel.go:91
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
nil, // args
)
}
View on GitHub (pinned to 24529f1404)
Solutions
- Verify the target exchange and queue still exist and bindings are correct.
- Retry the publish after checking broker health (alarms, disk/memory).
- Re-declare the exchange/queue topology before publishing if topology drift is suspected.
Example fix
// before
if err := ch.Publish(ex, key, msg); err != nil { return err }
// after
if err := ch.Publish(ex, key, msg); err != nil && strings.Contains(err.Error(), "received nack") {
if derr := declareTopology(ch, ex); derr != nil { return derr }
return ch.Publish(ex, key, msg)
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify exchange/queue topology before publishing
if err := ch.DeclareExchange(ex); err != nil { return err } Try / catch
if err := ch.Publish(ex, key, msg); err != nil {
if strings.Contains(err.Error(), "received nack") {
return fmt.Errorf("broker rejected message: %w", err) // do not blind-retry
}
return err
} Prevention
- Re-declare exchanges/queues on startup and after reconnects.
- Check RabbitMQ alarms (memory/disk) before high-volume publishing.
- Alert on nacks instead of auto-retrying, since nacks usually mean topology/broker issues.
When it happens
Trigger: RabbitMQ nacks a confirm-mode publish — typically when the broker cannot route/persist the message (queue gone at publish time, internal broker error, mandatory/unroutable scenarios).
Common situations: Publishing to an exchange/queue that was deleted; broker memory/disk alarms causing rejections; transient broker instability under load.
Related errors
- channel closed before could receive confirmation of publish
- channel is nil
- connection is nil
- not connected
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/ab0e4216197aaf5e.
Report an issue: GitHub.