Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue 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)

Đang mở
#313 7 bình luận 0 reaction 0 người được giao Xem trên GitHub

@abhiramaab đang làm issue này rồi.

Từ ngày 2/10/2026.

  • #314 của @abhiramaab — đã đóng, không merge

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
55/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java
Lĩnh vực
backend, networking

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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).

Ngôn ngữ chính
Java
Star
805
Fork
99
Merge trung bình
12 giờ 35 phút
Pull request đã merge (30 ngày)
3

Chuẩn bị môi trường

  • Có Dockerfile hoặc tệp Docker Compose
  • Không có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của apache/bifromq

Tất cả issue của apache/bifromq

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.