KubeMQ
ConnectorsSTOMPReference

Error Frames

The complete ERROR-frame vocabulary the KubeMQ STOMP connector emits — handshake, codec, dispatch, SEND, SUBSCRIBE, and RPC errors, plus receipt rules.

This is the complete, verified vocabulary of ERROR-frame message strings the KubeMQ STOMP connector emits — the trigger for each, the receipt rules, and the one failure mode that is not an ERROR frame at all: the RPC stomp-error header.

ERROR is terminal

Every protocol error produces an ERROR frame followed immediately by a socket close. There is no recovery on the same connection — the client must reconnect. The message string is sanitized: internal error text, stack chains, and file paths never cross the wire.

The connector has three ERROR-emit paths, all of which close the connection:

FunctionPhase
writeErrorSynchandshake (before the write loop starts)
sendErrorpost-CONNECT frame dispatch
sendErrorAsyncconnector shutdown broadcast

An ERROR frame carries message:<sanitized text> and, when a detail is provided, a content-type:text/plain body with a short human-readable explanation.

The ERROR-frame vocabulary (complete)

Every message string the connector can emit, grouped by phase. The detail column shows the optional ERROR body where one is set.

Handshake errors (before CONNECTED)

messageDetail bodyTrigger
malformed framefirst frame must be CONNECT or STOMPfirst frame is not CONNECT / STOMP within 30 s
broker not readythe message broker not ready at CONNECT (gate before auth)
connection limit reachedMaxConnections exceeded (counted at accept; ERROR deferred to handshake)
authentication failedpasscode JWT rejected (no detail — no leakage)
version-negotiation ERRORno common accept-version; the ERROR carries version:1.0,1.1,1.2

Frame-codec errors (read loop)

messageDetail bodyTrigger
frame too largeframe exceeds 64 headers / 8 KiB header block / MaxBodySize
malformed frameunparseable frame; body on a non-SEND command; bad escaping; lone CR

Dispatch errors (post-CONNECT)

messageDetail bodyTrigger
transactions not supportedBEGIN / COMMIT / ABORT, or any frame carrying a transaction header
malformed framealready connecteda second CONNECT / STOMP after the handshake
unknown command— (offending command echoed, sanitized)an unrecognized command

SEND errors

messageDetail bodyTrigger
invalid destinationmissing destination headerSEND with no / empty destination
invalid destinationbad destination grammar (empty segment, empty channel, no pattern, too long, wildcard on SEND)
invalid destinationcannot SEND to reply destinationsSEND to a /reply/ destination
access deniedCasbin Enforce(write) denied
broker not readythe message broker not ready at SEND time (SENDs do not buffer)
frame too largetoo many headers or header value too large>32 custom tags or a tag value >4096 bytes
message rejectedthe array publish call returned an error (sanitized; detail in server log)

SUBSCRIBE errors

messageDetail bodyTrigger
selectors not supporteda selector header on SUBSCRIBE
invalid destinationmissing destination headerSUBSCRIBE with no / empty destination
invalid subscriptionid header requiredno id on 1.1 / 1.2
invalid subscriptionunknown ack modeack is not auto / client / client-individual
invalid destinationbad destination grammar
cannot subscribe to RPC destinationsSUBSCRIBE to /command/ or /query/ (STOMP is requester-only)
invalid subscriptionduplicate subscription idthe id is already in use on this connection
access deniedCasbin Enforce(read) denied (queues / events / store)
invalid subscription<replay error>bad Events-Store start-from / start-value combination

UNSUBSCRIBE / ACK / NACK errors

messageDetail bodyTrigger
invalid subscriptionmissing idUNSUBSCRIBE with no resolvable id
invalid subscriptionunknown subscription idUNSUBSCRIBE for an id this connection never created

ACK / NACK never close on an unknown, expired, or foreign token — the late ack is silently ignored and the RECEIPT (if requested) is still sent.

RPC SEND errors (the only RPC failures that close the connection)

messageDetail bodyTrigger
reply-to subscription requiredthe reply-to does not name an active /reply/ sub on the same connection
too many pending requestsRpcMaxPending (default 1024) exceeded

Everything else about an RPC failure (timeout, logical error, dropped reply) is not an ERROR frame — see RPC stomp-error.

Shutdown

messageDetail bodyTrigger
server shutting downconnector Close() broadcasts to every live connection, then drains ≤10 s

Receipt semantics

The receipt header requests a RECEIPT confirmation frame. The rules:

  • A receipt header is honored on every processed client frame (SEND, SUBSCRIBE, UNSUBSCRIBE, ACK, NACK, DISCONNECT).
  • RECEIPT is enqueued after the frame's processing completes:
    • SEND (events / store / queues): after the array call returns successfully.
    • RPC SEND (/command / /query): after dispatch acceptance — before the reply MESSAGE arrives.
  • A RECEIPT means "KubeMQ accepted the frame", NOT "a consumer received the message." Do not treat a SEND RECEIPT as a delivery confirmation.

Handlers that close the connection on an ERROR path NEVER send a RECEIPT. The STOMP spec permits an ERROR in lieu of a RECEIPT. So a SEND to a bad destination that carried a receipt header returns an ERROR and no RECEIPT — never block forever waiting for one.

A DISCONNECT with a receipt header flushes the RECEIPT to the wire before the socket closes (deterministic graceful shutdown). This is the clean way to confirm a graceful close.

RPC stomp-error: a failure that is NOT an ERROR frame

RPC failures arrive as a MESSAGE with a stomp-error header, NOT an ERROR frame. A timeout, a logical error, or a dropped reply is delivered as data on your /reply/ subscription, and the connection stays open. Only reply-to violations and pending-cap overflow (above) close the connection.

The reply MESSAGE has three shapes, only two of which are empty-bodied:

ShapeConditionstomp-error valueBody
(a) Logical errorresp.Error != "" && !resp.Executed<sanitized resp.Error>carries the responder's body + tags — NOT empty
(b) Transport error / timeouterr != niltimeout / request cancelled / <sanitized err>empty
(c) Nil responseresp == nilno responseempty

Detect RPC failure by the presence of the stomp-error header, NOT by an empty body. A logical error (shape a) returns a fully-populated body and tags alongside stomp-error. Code that keys on "empty body" will misclassify logical errors.

Go context errors map to stable strings:

Go error containsstomp-error value
context deadline exceededtimeout
context canceledrequest cancelled
(anything else)the sanitized error text

A reply MESSAGE is best-effort — if the connection's output queue is full it is dropped (metric rpc_response / dropped), again without closing the connection. See Commands and Queries.

Error-detail sanitization

Every destination-class trigger is mapped to one of three sanitized strings before it reaches the wire:

Trigger classWire message
frame-too-large violationsframe too large
empty segment / empty channel / no pattern / too long / wildcard not allowedinvalid destination
anything elsemalformed frame

Header values and command names that are echoed in an ERROR (for example, the offending command in unknown command) are sanitized first.

Was this page helpful?

On this page