镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

[Bug] Delay messages are delivered with internal properties leaked into propertiesString (ScheduleMessageService#messageTimeUp) #11037

Open

Description

@unbridled-41

Before Creating the Bug Report

  • I found a bug, not just asking a question, which should be created in GitHub Discussions.
  • I have searched the GitHub Issues and GitHub Discussions of this repository and believe that this is not a duplicate.
  • I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.

Runtime platform environment

Linux, JDK 21, develop (ff8f6f7)

RocketMQ version

5.x develop

Describe the Bug

ScheduleMessageService#messageTimeUp (broker/src/main/java/org/apache/rocketmq/broker/schedule/ScheduleMessageService.java) encodes the delivered message's propertiesString before the internal properties are cleared:

msgInner.setPropertiesString(MessageDecoder.messageProperties2String(msgExt.getProperties())); // line 344 — encode
...
MessageAccessor.clearProperty(msgInner, MessageConst.PROPERTY_DELAY_TIME_LEVEL);   // line 353 — clear after
MessageAccessor.clearProperty(msgInner, MessageConst.PROPERTY_TIMER_DELIVER_MS);
MessageAccessor.clearProperty(msgInner, MessageConst.PROPERTY_TIMER_DELAY_SEC);

The propertiesString is what actually gets persisted in the commitlog and decoded on the consumer side, so every delay-level message delivered by ScheduleMessageService still carries DELAY_TIME_LEVEL (and TIMER_DELIVER_MS/TIMER_DELAY_SEC when the producer used timer properties) on the wire, while the broker-side property map no longer has them. The property map and the wire data disagree; SQL92 property filtering and user code see stale internal properties.

This is the exact defect class fixed for the timer-wheel path in #10972 / commit e533b66 (TimerMessageStore#convertMessage now encodes after clearing). The same pattern in ScheduleMessageService#messageTimeUp predates it (old unmerged PR #4190 tried to address it in 2022) and was not covered by that fix.

Steps to Reproduce

  1. Send a message with setDelayTimeLevel(n).
  2. When the delay expires, messageTimeUp re-writes it into the real topic.
  3. Consume the message: message.getProperties() / getProperty("DELAY_TIME_LEVEL") (decoded from propertiesString) still returns the internal delay properties.

Expected Behavior

The delivered message's propertiesString must be encoded after the internal properties are cleared, so the property map and the wire data are consistent and no internal properties leak to consumers.

Corresponding PR

Activity

  1. RockteMQ-AI commented on Sep 5, 2026

    @RockteMQ-AI
    Contributor

    Issue Evaluation

    Category: type/bug | Status: Confirmed

    The reported issue has been verified against the current codebase on the develop branch.

    Root Cause: In ScheduleMessageService#messageTimeUp, setPropertiesString() is called before clearProperty() for PROPERTY_DELAY_TIME_LEVEL, PROPERTY_TIMER_DELIVER_MS, and PROPERTY_TIMER_DELAY_SEC. The propertiesString is what gets persisted into the commitlog and decoded by consumers, so the wire data still carries these internal properties even though the broker-side property map has been cleaned up.

    Code Evidence (develop branch):

    // Line ~344 — encodes propertiesString BEFORE clearing
    msgInner.setPropertiesString(MessageDecoder.messageProperties2String(msgExt.getProperties()));
    // ...
    // Lines ~353-355 — clears properties AFTER encoding (too late for propertiesString)
    MessageAccessor.clearProperty(msgInner, MessageConst.PROPERTY_DELAY_TIME_LEVEL);
    MessageAccessor.clearProperty(msgInner, MessageConst.PROPERTY_TIMER_DELIVER_MS);
    MessageAccessor.clearProperty(msgInner, MessageConst.PROPERTY_TIMER_DELAY_SEC);

    Impact: Consumers receive stale internal delay properties via getProperties() / getProperty("DELAY_TIME_LEVEL"). SQL92 property filtering on these properties will see incorrect values. The property map and wire data are inconsistent.

    Severity: Medium — data correctness issue for delay message consumers; does not cause message loss or broker crash.

    Fix: Move setPropertiesString() to after the clearProperty() calls, consistent with the timer-wheel fix in commit e533b66 (#10972).

    An automated fix proposal will be generated. Reply /approve to proceed with PR generation.


    Automated evaluation by github-manager-bot

  2. RockteMQ-AI commented on Sep 6, 2026

    @RockteMQ-AI
    Contributor

    Issue Evaluation

    Category: bug | Status: Confirmed

    Verified against the current develop branch. The bug is in ScheduleMessageService#messageTimeUp:

    • Line 344: msgInner.setPropertiesString(MessageDecoder.messageProperties2String(msgExt.getProperties())) encodes the properties string before internal properties are cleared.
    • Lines 353-355: clearProperty calls for PROPERTY_DELAY_TIME_LEVEL, PROPERTY_TIMER_DELIVER_MS, and PROPERTY_TIMER_DELAY_SEC modify the in-memory map but not the already-encoded propertiesString.

    Root Cause: Properties string serialization happens before internal property removal, causing timer/delay internal properties to leak into the delivered message's propertiesString.

    Impact: Consumers receiving delay/timer messages will see internal properties in their propertiesString, which should be transparent to end users.

    Severity: Medium — functional correctness is not affected (delivery timing is correct), but the API contract is violated.

    Fix direction: Move setPropertiesString to after the clearProperty calls, or re-encode the properties string after clearing.

    An automated fix proposal will be generated. Reply /approve to proceed with PR generation.


    Automated evaluation by RockteMQ-AI

  3. RockteMQ-AI commented on Sep 17, 2026

    @RockteMQ-AI
    Contributor

    Issue Evaluation

    Category: bug | Status: Confirmed

    This is a valid bug in the delay message delivery logic. The issue correctly identifies that delay messages are delivered with internal properties leaked into propertiesString.

    Root Cause: The ScheduleMessageService#messageTimeUp method does not properly filter out internal properties before delivery.

    Impact: Internal implementation details are exposed to consumers, breaking encapsulation and potentially causing confusion.

    Severity: Low-Medium - affects message property cleanliness, not functionality.

    Assessment: The fix should filter out internal properties (those starting with specific prefixes) before delivering delay messages.

    An automated fix proposal can be generated. Reply /approve to proceed with PR generation.


    Automated evaluation by RockteMQ-AI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions