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

  1. Ensure the client sets the Will flag whenever Will Retain is set.
  2. If no will message is intended, clear the Will Retain bit.
  3. 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

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


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