nats-io/nats-server · error
connect flags reserved bit not set to 0
Error message
connect flags reserved bit not set to 0
What it means
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].
Source
Thrown at server/mqtt.go:235
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")
errMQTTInvalidRetainFlags = errors.New("invalid retained message flags")
errMQTTInvalidRetainedMessage = errors.New("invalid retained message")
errMQTTSessionCollision = errors.New("stored session does not match client ID")
errMQTTInvalidPublishLength = errors.New("invalid publish message, variable header exceeds remaining length")
errMQTTAckPipelineStopped = errors.New("QoS1 PUBACK pipeline has shut down while admitting a message, " +
"abandoning the wait for its JetStream ack; failing the connection, " +
"the client will re-send unacknowledged PUBLISH packets on reconnect")
)
View on GitHub (pinned to 3a66a489d2)
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.
Example fix
// before (client-side encode) flags := 0x01 // reserved bit wrongly set // after flags := 0x00 // reserved bit must be 0 per [MQTT-3.1.2-3]
Defensive patterns
Strategy: validation
Validate before calling
// client side, before sending CONNECT
if flags&0x01 != 0 {
return fmt.Errorf("reserved connect-flags bit must be 0")
} Try / catch
// server-side callers of mqttReadConnect return this to the client // client side: check the CONNACK/close reason for the reserved-bit message and fix the encoder
Prevention
- 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.
When it happens
Trigger: 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}).
Common situations: 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.
Related errors
- if Will flag is set to 0, Will Retain flag must be 0 too
- password flag set but username flag is not
- when client ID is empty, clean session flag must be set to 1
- empty Will topic not allowed
- empty user name not allowed
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/3a975d1736c95774.
Report an issue: GitHub.