nats-io/nats-server · error
topic filter cannot be empty
Error message
topic filter cannot be empty
What it means
`errMQTTTopicFilterCannotBeEmpty` is returned when an MQTT SUBSCRIBE or UNSUBSCRIBE packet contains a topic filter of zero length. The MQTT spec requires at least one non-empty topic filter; the parser (server/mqtt.go:5317) rejects empty topic strings before processing the subscription.
Source
Thrown at server/mqtt.go:226
)
var (
sparkbNamespaceTopicPrefix = []byte("spBv1.0/")
sparkbCertificatesTopicPrefix = []byte("$sparkplug/certificates/")
)
var (
mqttPingResponse = []byte{mqttPacketPingResp, 0x0}
mqttProtoName = []byte("MQTT")
mqttOldProtoName = []byte("MQIsdp")
mqttSessJailDur = mqttSessFlappingJailDur
mqttFlapCleanItvl = mqttSessFlappingCleanupInterval
mqttRetainedCacheTTL = mqttDefaultRetainedCacheTTL
)
var (
errMQTTNotWebsocketPort = errors.New("MQTT clients over websocket must connect to the Websocket port, not the MQTT port")
errMQTTTopicFilterCannotBeEmpty = errors.New("topic filter cannot be empty")
errMQTTMalformedVarInt = errors.New("malformed variable int")
errMQTTSecondConnectPacket = errors.New("received a second CONNECT packet")
errMQTTServerNameMustBeSet = errors.New("mqtt requires server name to be explicitly set")
errMQTTUserMixWithUsersNKeys = errors.New("mqtt authentication username not compatible with presence of users/nkeys")
errMQTTTokenMixWIthUsersNKeys = errors.New("mqtt authentication token not compatible with presence of users/nkeys")
errMQTTAckWaitMustBePositive = errors.New("ack wait must be a positive value")
errMQTTJSAPITimeoutMustBePositive = errors.New("JS API timeout must be a positive value")
errMQTTStandaloneNeedsJetStream = errors.New("mqtt requires JetStream to be enabled if running in standalone mode")
errMQTTConnFlagReserved = errors.New("connect flags reserved bit not set to 0")
errMQTTWillAndRetainFlag = errors.New("if Will flag is set to 0, Will Retain flag must be 0 too")
errMQTTPasswordFlagAndNoUser = errors.New("password flag set but username flag is not")
errMQTTCIDEmptyNeedsCleanFlag = errors.New("when client ID is empty, clean session flag must be set to 1")
errMQTTEmptyWillTopic = errors.New("empty Will topic not allowed")
errMQTTEmptyUsername = errors.New("empty user name not allowed")
errMQTTTopicIsEmpty = errors.New("topic cannot be empty")
errMQTTPacketIdentifierIsZero = errors.New("packet identifier cannot be 0")
errMQTTUnsupportedCharacters = errors.New("character not supported for MQTT topics")
errMQTTInvalidSession = errors.New("invalid MQTT session")View on GitHub (pinned to 3a66a489d2)
Solutions
- Fix the client to always include a non-empty topic filter string in SUBSCRIBE/UNSUBSCRIBE packets
- Use a standard MQTT client library instead of hand-built packets
- Verify packet framing: check that the 2-byte big-endian topic length matches the actual topic bytes sent
Example fix
// before: empty topic filter
packet := []byte{0x82, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00}
// after: subscribe to topic "foo"
packet := []byte{0x82, 0x08, 0x00, 0x01, 0x00, 0x03, 'f', 'o', 'o', 0x00} Defensive patterns
Strategy: validation
Validate before calling
// Validate topic filters before sending SUBSCRIBE
for (const t of topics) { if (typeof t !== 'string' || t.length === 0) throw new Error('topic filter cannot be empty') } Prevention
- Use standard MQTT client libraries instead of hand-built packets
- Add unit tests for packet encoding incl. length prefixes
- Reject empty topics at the application layer before publish/subscribe
When it happens
Trigger: Sending a SUBSCRIBE/UNSUBSCRIBE packet whose topic-filter length field is 0; a buggy or hand-rolled MQTT client encoding an empty topic; corrupt packet framing that misaligns topic-length bytes so a zero length is parsed.
Common situations: Custom MQTT clients or test harnesses building packets manually; protocol fuzzing; a misencoded UTF-16 client (MQTT topics are UTF-8) sending wrong length prefixes.
Related errors
- malformed variable int
- received a second CONNECT packet
- connect flags reserved bit not set to 0
- if Will flag is set to 0, Will Retain flag must be 0 too
- password flag set but username flag is not
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/d0553c4e031c87c0.
Report an issue: GitHub.