{"record":{"id":"1ded6c8355d5261b","repo":"nats-io/nats-server","slug":"invalid-fixed-header-flags-x-for-packet-type-x","errorCode":null,"errorMessage":"invalid fixed header flags %x for packet type %x","messagePattern":"invalid fixed header flags %x for packet type %x","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":1012,"sourceCode":"\t}\n\treturn err\n}\n\nfunc mqttCheckFixedHeaderFlags(packetType, flags byte) error {\n\tvar expected byte\n\tswitch packetType {\n\tcase mqttPacketConnect, mqttPacketPubAck, mqttPacketPubRec, mqttPacketPubComp,\n\t\tmqttPacketPing, mqttPacketDisconnect:\n\t\texpected = 0\n\tcase mqttPacketPubRel, mqttPacketSub, mqttPacketUnsub:\n\t\texpected = 0x2\n\tcase mqttPacketPub:\n\t\treturn nil\n\tdefault:\n\t\treturn nil\n\t}\n\tif flags != expected {\n\t\treturn fmt.Errorf(\"invalid fixed header flags %x for packet type %x\", flags, packetType)\n\t}\n\treturn nil\n}\n\nfunc mqttCheckRemainingLength(packetType byte, pl int) error {\n\tvar expected int\n\tswitch packetType {\n\tcase mqttPacketConnect, mqttPacketPub, mqttPacketSub, mqttPacketUnsub:\n\t\treturn nil\n\tcase mqttPacketPubAck, mqttPacketPubRec, mqttPacketPubRel, mqttPacketPubComp:\n\t\texpected = 2\n\tcase mqttPacketPing, mqttPacketDisconnect:\n\t\texpected = 0\n\tdefault:\n\t\treturn nil\n\t}\n\tif pl != expected {\n\t\treturn fmt.Errorf(\"invalid remaining length %d for packet type %x\", pl, packetType)","sourceCodeStart":994,"sourceCodeEnd":1030,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L994-L1030","documentation":"MQTT requires that each packet type carry specific values in the 4 fixed-header flag bits (DUP/QoS/RETAIN); most types mandate zero. mqttCheckFixedHeaderFlags computes the expected flags per packet type and raises this error when the received flags (lower nibble) don't match. Validated immediately after reading the first fixed-header byte.","triggerScenarios":"A client sends e.g. a PUBREL/SUBSCRIBE/UNSUBSCRIBE/PINGREQ with nonzero flag bits, or a PUBLISH whose QoS bits are invalid (QoS 3). The check compares flags against mqttCheckFixedHeaderFlags's expected table and errors with fmt.Errorf(\"invalid fixed header flags %x for packet type %x\", flags, packetType).","commonSituations":"Hand-rolled or buggy client serialization; bit-manipulation mistakes in custom bridges; corrupted frames from a faulty proxy; fuzz testing.","solutions":["Fix the client's fixed-header serialization: set the flag nibble to 0 for all packet types except PUBLISH (DUP/QoS/RETAIN) and validate QoS <= 2.","Enable MQTT trace logging to see the offending packet type and flags.","Check any intermediate bridge/proxy that re-serializes MQTT frames.","Per MQTT spec, treat this as a protocol error and reconnect with a corrected encoder."],"exampleFix":"// before: wrong flags on PUBREL\nwriteByte(0x62); // flags=2\n// after: PUBREL flags must be 0x2? no - must be 0b0010; correct per type\nwriteByte(0x60 | 0x02); // PUBREL fixed header is 0x62 by spec; for types expecting 0 use 0x<type><<4>","handlingStrategy":"validation","validationCode":"// Validate fixed-header flags per type before sending (MQTT 3.1.1 table)\nconst flagsFor = t => t === 3 ? undefined /* DUP/QoS/RETAIN */ : 0;\nif (type !== 3 && (byte & 0x0F) !== 0) throw new Error('flags must be 0 for type ' + type);","typeGuard":"function hasValidFlags(fixedHeaderByte, packetType) {\n  if (packetType === 3) return (fixedHeaderByte & 0x06) !== 0x06; // QoS must not be 3\n  return (fixedHeaderByte & 0x0F) === 0;\n}","tryCatchPattern":null,"preventionTips":["Set flag nibble to 0 for every packet type except PUBLISH","Never encode QoS 3 (0b11) on PUBLISH","Unit-test your MQTT serializer against the spec's fixed-header table","Avoid proxies that rewrite raw MQTT frames"],"tags":["mqtt","protocol-violation","malformed-packet"],"backgroundTag":"malformed-mqtt-header","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}