{"record":{"id":"d0553c4e031c87c0","repo":"nats-io/nats-server","slug":"topic-filter-cannot-be-empty","errorCode":null,"errorMessage":"topic filter cannot be empty","messagePattern":"topic filter cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":226,"sourceCode":")\n\nvar (\n\tsparkbNamespaceTopicPrefix    = []byte(\"spBv1.0/\")\n\tsparkbCertificatesTopicPrefix = []byte(\"$sparkplug/certificates/\")\n)\n\nvar (\n\tmqttPingResponse     = []byte{mqttPacketPingResp, 0x0}\n\tmqttProtoName        = []byte(\"MQTT\")\n\tmqttOldProtoName     = []byte(\"MQIsdp\")\n\tmqttSessJailDur      = mqttSessFlappingJailDur\n\tmqttFlapCleanItvl    = mqttSessFlappingCleanupInterval\n\tmqttRetainedCacheTTL = mqttDefaultRetainedCacheTTL\n)\n\nvar (\n\terrMQTTNotWebsocketPort           = errors.New(\"MQTT clients over websocket must connect to the Websocket port, not the MQTT port\")\n\terrMQTTTopicFilterCannotBeEmpty   = errors.New(\"topic filter cannot be empty\")\n\terrMQTTMalformedVarInt            = errors.New(\"malformed variable int\")\n\terrMQTTSecondConnectPacket        = errors.New(\"received a second CONNECT packet\")\n\terrMQTTServerNameMustBeSet        = errors.New(\"mqtt requires server name to be explicitly set\")\n\terrMQTTUserMixWithUsersNKeys      = errors.New(\"mqtt authentication username not compatible with presence of users/nkeys\")\n\terrMQTTTokenMixWIthUsersNKeys     = errors.New(\"mqtt authentication token not compatible with presence of users/nkeys\")\n\terrMQTTAckWaitMustBePositive      = errors.New(\"ack wait must be a positive value\")\n\terrMQTTJSAPITimeoutMustBePositive = errors.New(\"JS API timeout must be a positive value\")\n\terrMQTTStandaloneNeedsJetStream   = errors.New(\"mqtt requires JetStream to be enabled if running in standalone mode\")\n\terrMQTTConnFlagReserved           = errors.New(\"connect flags reserved bit not set to 0\")\n\terrMQTTWillAndRetainFlag          = errors.New(\"if Will flag is set to 0, Will Retain flag must be 0 too\")\n\terrMQTTPasswordFlagAndNoUser      = errors.New(\"password flag set but username flag is not\")\n\terrMQTTCIDEmptyNeedsCleanFlag     = errors.New(\"when client ID is empty, clean session flag must be set to 1\")\n\terrMQTTEmptyWillTopic             = errors.New(\"empty Will topic not allowed\")\n\terrMQTTEmptyUsername              = errors.New(\"empty user name not allowed\")\n\terrMQTTTopicIsEmpty               = errors.New(\"topic cannot be empty\")\n\terrMQTTPacketIdentifierIsZero     = errors.New(\"packet identifier cannot be 0\")\n\terrMQTTUnsupportedCharacters      = errors.New(\"character not supported for MQTT topics\")\n\terrMQTTInvalidSession             = errors.New(\"invalid MQTT session\")","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L208-L244","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: empty topic filter\npacket := []byte{0x82, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00}\n// after: subscribe to topic \"foo\"\npacket := []byte{0x82, 0x08, 0x00, 0x01, 0x00, 0x03, 'f', 'o', 'o', 0x00}","handlingStrategy":"validation","validationCode":"// Validate topic filters before sending SUBSCRIBE\nfor (const t of topics) { if (typeof t !== 'string' || t.length === 0) throw new Error('topic filter cannot be empty') }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["mqtt","protocol","topic-filter","malformed-packet"],"backgroundTag":"mqtt-protocol-violation","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}