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

  1. Fix the client to clear the reserved bit (flags &= ^0x01) when constructing the CONNECT packet.
  2. Use a compliant MQTT client library instead of hand-encoding packets.
  3. 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

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


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/3a975d1736c95774. Report an issue: GitHub.