Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Inbound and outbound packet-size checks differ, so a QoS 1 message just under MaxUserPayloadBytes is accepted but never delivered (blocks a persistent subscriber)

Abierto
#313 7 comentarios 0 reacciones 0 asignados Ver en GitHub

@abhiramaab ya está trabajando en esto.

Desde el 2/10/2026.

  • #314 de @abhiramaab — cerrado sin fusionar

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
55/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
java

Línea de trabajo

Start with ChannelAttrs.setMaxPayload and the inbound MqttDecoder(maxUserPayloadSize), then compare that limit with MQTT3MessageSizer and MQTTPacketFilter on outbound delivery. Inspect MQTTSessionHandler.writeConfirmableSubMessage and the related resend behavior; done means accepted messages are deliverable or are dropped and confirmed without blocking the subscriber's in-flight window.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Version: 4.0.0-incubating (standalone, default DevOnlySettingProvider)

Summary

MaxUserPayloadBytes (stored as TenantSettings.maxPacketSize) is enforced differently in the two directions:

  • Inbound (publisher → broker): the replacement MqttDecoder(maxPacketSize) compares the fixed header's remaining length R against the limit. A packet is accepted while R ≤ L.
  • Outbound (broker → subscriber): MQTTPacketFilter drops a packet whose full encoded size 1 + varint(R) + R is over the limit (MQTT3MessageSizer), reporting OversizePacketDropped and never completing the write.

So a QoS 1 PUBLISH whose remaining length is within 3 bytes of the limit (R = L−2 … L for L = 16384) is accepted and PUBACKed from the publisher, stored in the subscriber's inbox, and then dropped on every delivery attempt. writeConfirmableSubMessage keeps it in the unconfirmed set and resend() retries it until MaxResendTimes. With a large MaxResendTimes, a persistent subscriber's in-flight window fills with undeliverable messages and no further QoS 1 is delivered to it until the session is reset.

For MQTT 5 subscribers this cannot be worked around from the client: MQTT5ConnectHandler rejects a client Maximum Packet Size above maxPacketSize (CONNACK 0x83), and MQTTPacketFilter uses min(clientMax, settings.maxPacketSize).

Reproduction

  1. Start the broker with -DMaxUserPayloadBytes=16384 (and a large -DMaxResendTimes).
  2. Subscriber: MQTT 3.1.1, cleanSession=false, QoS 1, manual acks.
  3. Publisher (same tenant): QoS 1 publishes with remaining length 16382, 16383, 16384 (payload = R − 2 − topicLength − 2), followed by a small normal message.
  4. The publisher gets PUBACKs for all of them; the subscriber receives none (not even the normal message once ~8 undeliverable messages occupy the window).

Expected

Both directions use the same measure, e.g. the inbound decoder limit is maxPacketSize − 5 (the maximum fixed-header overhead), or the outbound filter compares the remaining length, so anything accepted inbound is deliverable to a subscriber with the same limit. Independently, MQTTSessionHandler.writeConfirmableSubMessage already drops-and-confirms a confirmable message for NoSubPermission, Duplicated and NoLocal; doing the same when the encoded size exceeds the subscriber's limit (report a drop event, confirm(packetId, false)) would stop an undeliverable message from occupying the in-flight window until MaxResendTimes.

Checked against main (2026-10-02, 1394131): still present. #279 ("Fix oversized packet mem leakage", merged 2026-08-31, not yet released) makes MQTTPacketFilter release the buffer and complete the write promise, but the message stays unconfirmed in the session, and the inbound MqttDecoder(maxUserPayloadSize) in ChannelAttrs.setMaxPayload still compares the remaining length.

Related: apache/bifromq#258 (resend cancelled by PUBACK), apache/bifromq#289 (resend chain stops after a MaxRetried drop), #279 (oversized-packet buffer leak).

Lenguaje dominante
Java
Estrellas
805
Forks
99
Merge medio
12 h 35 min
PR fusionados (30 d)
3

Preparar el entorno

  • Incluye un Dockerfile o un archivo de Docker Compose
  • Sin plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de apache/bifromq

Todos los issues de apache/bifromq

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.