Ahh, you'll need to add a bit of logic in your application to resend if the NATS streaming publish fails. More detail inline...
COLIN: Sure. It boils down to a few things. Core NATS (underneath NATS streaming) provides a guarantee of "at most once" delivery. Early on in the clients we made the architectural decision to buffer messages and flush periodically on a connection for performance reasons. Most clients behave this way. If the connection is terminated in the process of writing a message to the socket, you may have a partial message written, or possibly have written the entire message to the socket buffer, but the client doesn't know if the message made it to the server. Even if it made it to the server, there's no guarantee it'll make it to the final destination(s).
When the client flushes the buffer after reconnect, the NATS server will discard partial messages (protocol error) resulting a dropped message, or if the message never made it to the server, then it disappeared during the socket disconnect event. Complete messages in the client's reconnect buffer will succeed in being processed by the server assuming all is going well at that point.
Since core NATS guarantees at most once delivery, we won't re-send messages from a publisher. JetStream (and NATS Streaming) however do provide at least once semantics (and exactly once for JetStream) using acknowledgments atop core NATS. A successful publish acknowledgment guarantees that message has been stored in NATS, and we leave it up to the application to attempt resend any messages that didn't receive a successful publish acknowledgment. Different use cases will employ various retry strategies, determine when to give up, and dictate what to do when a message cannot be published into the NATS system.
The simplest method is to keep retrying publish calls on a publish acknowledgment failure until reconnected. You can use the disconnected / reconnected callbacks to pause publishing or check connection state in most clients.