Why STOMP Receipts and Errors Don’t Play Well on One Connection
STOMP is layered on top of TCP, which is a byte stream, not message-oriented. When you use a single TCP connection for both sending client frames and receiving server frames, two problems arise:
- Interleaving ambiguity
The client cannot strictly associate an incomingERROR
orRECEIPT
frame with the exact outbound frame that triggered it, because inbound frames arrive asynchronously and may be intermixed with unrelated messages (e.g. aMESSAGE
from a subscription). TCP guarantees order of bytes, not logical pairing of request–response. - State confusion under error conditions
If the server sends anERROR
frame, it may apply to a specific client command, to a subscription, or to the connection as a whole. Over a shared connection, the client may still have pending sends “in flight” when the error is received, making it unclear which ones succeeded, failed, or need to be retried.
In short: TCP multiplexes all traffic into one ordered stream, but STOMP requires the client to distinguish between different categories of frames (responses, errors, and unrelated deliveries). This mismatch makes a single-connection setup prone to race conditions and mis-association of responses.
👉 That’s why some designs prefer separate connections for send-only vs. receive-only paths (or use correlation IDs carefully), to reduce ambiguity.
Below is a timeline diagram to make the interleaving problem visually clear:

Here’s the timeline:
- The client sends two frames (
SEND id=1
, thenSEND id=2
). - The server interleaves unrelated
MESSAGE
frames with theRECEIPT
for id=1. - An
ERROR
arrives, but it’s unclear whether it corresponds toSEND id=2
or some other condition.
This illustrates why a single TCP connection makes associating responses with requests error-prone — asynchronous events from subscriptions are mixed with acknowledgments and errors.