{"record":{"id":"07409bcf2806f919","repo":"micro/go-micro","slug":"channel-closed-before-could-receive-confirmation-o","errorCode":null,"errorMessage":"channel closed before could receive confirmation of publish","messagePattern":"channel closed before could receive confirmation of publish","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"broker/rabbitmq/channel.go","lineNumber":87,"sourceCode":"func (r *rabbitMQChannel) Publish(exchange, key string, message amqp.Publishing) error {\n\tif r.channel == nil {\n\t\treturn errors.New(\"channel is nil\")\n\t}\n\n\tif r.confirmPublish != nil {\n\t\tr.mtx.Lock()\n\t\tdefer r.mtx.Unlock()\n\t}\n\n\terr := r.channel.Publish(exchange, key, false, false, message)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif r.confirmPublish != nil {\n\t\tconfirmation, ok := <-r.confirmPublish\n\t\tif !ok {\n\t\t\treturn errors.New(\"channel closed before could receive confirmation of publish\")\n\t\t}\n\n\t\tif !confirmation.Ack {\n\t\t\treturn errors.New(\"could not publish message, received nack from broker on confirmation\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (r *rabbitMQChannel) DeclareExchange(ex Exchange) error {\n\treturn r.channel.ExchangeDeclare(\n\t\tex.Name,         // name\n\t\tstring(ex.Type), // kind\n\t\tex.Durable,      // durable\n\t\tfalse,           // autoDelete\n\t\tfalse,           // internal\n\t\tfalse,           // noWait","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/broker/rabbitmq/channel.go#L69-L105","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Treat the message as undelivered-or-delivered (ambiguous): retry with an idempotency key if exactly-once semantics matter.","Enable automatic reconnect and re-open the channel, then republish.","Check RabbitMQ server logs for why the channel was closed at that moment."],"exampleFix":"// before\nif err := ch.Publish(ex, key, msg); err != nil { return err }\n// after\nif err := ch.Publish(ex, key, msg); err != nil {\n    if strings.Contains(err.Error(), \"closed before could receive confirmation\") {\n        return idempotentRepublish(ex, key, msg) // safe retry with dedupe key\n    }\n    return err\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := ch.Publish(ex, key, msg); err != nil {\n    if strings.Contains(err.Error(), \"closed before could receive confirmation\") {\n        reconnect(); return idempotentRepublish(ex, key, msg)\n    }\n    return err\n}","preventionTips":["Enable automatic reconnect on the AMQP connection.","Make publishes idempotent (dedupe key) since outcome is ambiguous.","Monitor broker logs for channel closes during publish bursts."],"tags":["rabbitmq","amqp","publisher-confirm","closed-channel"],"backgroundTag":"channel-closed-before-confirmation","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}