nats-io/nats-server · error
if Will flag is set to 0, Will Retain flag must be 0 too
Error message
if Will flag is set to 0, Will Retain flag must be 0 too
What it means
Per MQTT spec [MQTT-3.1.2-15], the Will Retain flag may only be set when the Will flag is set. During CONNECT parsing (server/mqtt.go:3836), if the Will flag is 0 but Will Retain is 1, the server rejects the packet with this error.
Source
Thrown at server/mqtt.go:236
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")
)
type srvMQTT struct {View on GitHub (pinned to 3a66a489d2)
Solutions
- Ensure the client sets the Will flag whenever Will Retain is set.
- If no will message is intended, clear the Will Retain bit.
- Verify the client library version encodes the MQTT 3.1.1 flag layout correctly.
Example fix
// before flags := mqttConnFlagWillRetain // retain without will flag // after flags := mqttConnFlagWillFlag | mqttConnFlagWillRetain
Defensive patterns
Strategy: validation
Validate before calling
// client side
if flags&willRetainBit != 0 && flags&willFlagBit == 0 {
return fmt.Errorf("Will Retain requires the Will flag")
} Try / catch
// client side: on connection rejection mentioning 'Will Retain', inspect and fix the flags byte before reconnect
Prevention
- Only set Will Retain through library APIs (SetWill with retain=true) which enforce the flag pairing.
- Compose connect flags from named bit constants.
- Add encoder tests covering every flag combination.
When it happens
Trigger: A CONNECT packet with connect flags having bit 5 (Will Retain) set while bit 2 (Will flag) is clear, e.g. flags byte 1<<5 as in the test case.
Common situations: Client code setting retain on a will message without also enabling the will flag, bitwise-flag assembly mistakes, or corrupted packets from non-compliant clients.
Related errors
- connect flags reserved bit not set to 0
- 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/ccbe93be78128554.
Report an issue: GitHub.