{"record":{"id":"3a975d1736c95774","repo":"nats-io/nats-server","slug":"connect-flags-reserved-bit-not-set-to-0","errorCode":null,"errorMessage":"connect flags reserved bit not set to 0","messagePattern":"connect flags reserved bit not set to 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":235,"sourceCode":"\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\")\n\terrMQTTInvalidRetainFlags         = errors.New(\"invalid retained message flags\")\n\terrMQTTInvalidRetainedMessage     = errors.New(\"invalid retained message\")\n\terrMQTTSessionCollision           = errors.New(\"stored session does not match client ID\")\n\terrMQTTInvalidPublishLength       = errors.New(\"invalid publish message, variable header exceeds remaining length\")\n\terrMQTTAckPipelineStopped         = errors.New(\"QoS1 PUBACK pipeline has shut down while admitting a message, \" +\n\t\t\"abandoning the wait for its JetStream ack; failing the connection, \" +\n\t\t\"the client will re-send unacknowledged PUBLISH packets on reconnect\")\n)\n","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L217-L253","documentation":"The MQTT 3.1.1 spec reserves bit 0 of the CONNECT packet's connect flags byte; it must be 0. When parsing a CONNECT packet, the server checks cp.flags&mqttConnFlagReserved and returns this error (server/mqtt.go:3822), rejecting the connection per spec [MQTT-3.1.2-3].","triggerScenarios":"A client sends a CONNECT packet whose connect-flags byte has the reserved bit set (e.g. payload byte 0x01 right after the protocol level, as in the test case {0,4,'M','Q','T','T',mqttProtoLevel,1}).","commonSituations":"Hand-rolled or buggy MQTT clients building the flags byte incorrectly, protocol-level corruption/fuzzing, or a client implementing a different protocol version whose flag layout differs.","solutions":["Fix the client to clear the reserved bit (flags &= ^0x01) when constructing the CONNECT packet.","Use a compliant MQTT client library instead of hand-encoding packets.","Capture the offending packet (network trace) to identify the misbehaving client and upgrade it."],"exampleFix":"// before (client-side encode)\nflags := 0x01 // reserved bit wrongly set\n// after\nflags := 0x00 // reserved bit must be 0 per [MQTT-3.1.2-3]","handlingStrategy":"validation","validationCode":"// client side, before sending CONNECT\nif flags&0x01 != 0 {\n    return fmt.Errorf(\"reserved connect-flags bit must be 0\")\n}","typeGuard":null,"tryCatchPattern":"// server-side callers of mqttReadConnect return this to the client\n// client side: check the CONNACK/close reason for the reserved-bit message and fix the encoder","preventionTips":["Use a maintained MQTT client library rather than hand-encoding packets.","Build flag bytes with named constants, never raw hex literals.","Fuzz-test packet encoders against a reference parser."],"tags":["mqtt","protocol","client-error"],"backgroundTag":"malformed-packet","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}