nats-io/nats-server · error
packet identifier cannot be 0
Error message
packet identifier cannot be 0
What it means
errMQTTPacketIdentifierIsZero is returned when an MQTT packet's packet identifier decodes to 0. The MQTT spec reserves packet ID 0 (identifiers must be 1-65535), so the server rejects SUBSCRIBE/PUBLISH packets carrying a zero identifier. It is produced in the packet-identifier decoding path at server/mqtt.go:5173.
Source
Thrown at server/mqtt.go:242
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 {
listener net.Listener
listenerErr error
authOverride bool
sessmgr mqttSessionManager
}
View on GitHub (pinned to 3a66a489d2)
Solutions
- Assign a non-zero packet identifier (1-65535) in the client before sending the SUBSCRIBE/PUBLISH packet.
- Implement monotonic packet-ID allocation with wraparound that skips 0 in your MQTT client.
- Fix test/generated byte sequences to encode a valid non-zero two-byte identifier.
Example fix
// before packetID := 0 writeUint16(buf, packetID) // after packetID := nextPacketID() // 1..65535, wraps and skips 0 writeUint16(buf, packetID)
Defensive patterns
Strategy: validation
Validate before calling
func validPacketID(id uint16) bool { return id >= 1 && id <= 65535 } Try / catch
if err := subscribe(topic, packetID); err != nil {
if strings.Contains(err.Error(), "packet identifier cannot be 0") {
packetID = nextPacketID()
return subscribe(topic, packetID)
}
return err
} Prevention
- Use a packet-ID allocator that never yields 0 and wraps 65535 -> 1
- Never hardcode 0 as a packet identifier in test fixtures or protocol builders
- Assert identifier validity in your MQTT encoder tests
When it happens
Trigger: A SUBSCRIBE (or QoS>0 PUBLISH) packet whose variable header contains two zero bytes as the packet identifier, e.g. []byte{0x00, 0x00}; the decoder returns (0, errMQTTPacketIdentifierIsZero).
Common situations: Client code that initializes the packet ID to 0 and forgets to assign/increment it; a misencoded test fixture; custom MQTT clients that treat 0 as a valid ID; corruption truncating fields so the ID is read as zeros.
Related errors
- topic cannot be empty
- with QoS=%v, packet identifier cannot be 0
- MQTT clients over websocket must connect to the Websocket po
- topic filter cannot be empty
- malformed variable int
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/c0444f211d59c13b.
Report an issue: GitHub.