{"record":{"id":"327ce249c6602b7d","repo":"nats-io/nats-server","slug":"jetstream-did-not-acknowledge-the-qos1-message-wit","errorCode":null,"errorMessage":"JetStream did not acknowledge the QoS1 message within %v (server is shutting down); failing the connection, the client will re-send unacknowledged PUBLISH packets on reconnect","messagePattern":"JetStream did not acknowledge the QoS1 message within (.+?) \\(server is shutting down\\); failing the connection, the client will re-send unacknowledged PUBLISH packets on reconnect","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/mqtt.go","lineNumber":4685,"sourceCode":"\tpipe := c.mqtt.acks\n\tif pipe == nil {\n\t\tif pipe = s.mqttPipelineStart(c, jsa); pipe == nil {\n\t\t\t// Server is shutting down, complete synchronously.\n\t\t\tt := time.NewTimer(jsa.timeout)\n\t\t\tdefer t.Stop()\n\t\t\tselect {\n\t\t\tcase err := <-ack.done:\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tc.mu.Lock()\n\t\t\t\ttrace := c.trace\n\t\t\t\tc.mu.Unlock()\n\t\t\t\tc.mqttEnqueuePubResponse(mqttPacketPubAck, ack.pi, trace)\n\t\t\t\treturn nil\n\t\t\tcase <-t.C:\n\t\t\t\tjsa.replies.Delete(ack.reply)\n\t\t\t\treturn fmt.Errorf(\"JetStream did not acknowledge the QoS1 message within %v \"+\n\t\t\t\t\t\"(server is shutting down); failing the connection, \"+\n\t\t\t\t\t\"the client will re-send unacknowledged PUBLISH packets on reconnect\", jsa.timeout)\n\t\t\tcase <-s.quitCh:\n\t\t\t\t// The reply may never come; do not hold up the shutdown.\n\t\t\t\tjsa.replies.Delete(ack.reply)\n\t\t\t\treturn ErrServerNotRunning\n\t\t\t}\n\t\t}\n\t\tc.mqtt.acks = pipe\n\t}\n\n\treturn pipe.push(ack)\n}\n\n// Admits an entry into the pipeline. Rejects it once the pipeline is\n// stopped: an entry admitted after the connection-close drain\n// (mqttHandleClosedClient -> pipe.shutdown) would strand its reply\n// registration in the account-scoped jsa.replies. readLoop only.","sourceCodeStart":4667,"sourceCodeEnd":4703,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L4667-L4703","documentation":"During server shutdown, the JetStream subscriber for MQTT QoS1 acks stops waiting: when the per-ack timer expires while the server is terminating, it fails the pending ack with this verbose error and the client connection is failed. The message tells the operator the client will recover by resending unacknowledged PUBLISH packets after reconnecting.","triggerScenarios":"A QoS1 PUBLISH is pending a JetStream ack and the server's quitCh fires; the ack timer then expires before JetStream responds, producing this shutdown-path error instead of the normal timeout message.","commonSituations":"Rolling restarts or graceful shutdown with in-flight QoS1 MQTT traffic, long JS ack latency coinciding with shutdown, operators draining a cluster with connected MQTT publishers.","solutions":["This is expected behavior during shutdown; ensure clients use clean-session=false and QoS1 so they re-send unacked PUBLISH on reconnect","Drain MQTT traffic before shutdown (stop publishers, wait for in-flight acks) to avoid the error","Reduce JS ack latency (storage tuning, quorum health) so acks complete before shutdown completes","Use nats-server's graceful shutdown wait time long enough for in-flight acks to settle"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"client.OnConnectionLost = func(_ mqtt.Client, err error) {\n  if strings.Contains(err.Error(), \"server is shutting down\") {\n    scheduleReconnectWithBackoff() // client resends unacked QoS1 PUBLISH automatically\n  }\n}","preventionTips":["Run MQTT clients with clean-session=false and manual-ack semantics so unacked QoS1 messages are resent","Drain/stop publishers before planned server restarts","Give the server a generous graceful shutdown wait period","Retry reconnect with exponential backoff during rolling deployments"],"tags":["mqtt","jetstream","shutdown","qos1","ack-timeout"],"backgroundTag":"jetstream-ack-timeout","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}