Skip to content

Regression in FilterSubjects Handling with DeliverAll/ReplayInstant between v2.10.25 and v2.10.26 #6824

Closed
@hampusohlsson

Description

@hampusohlsson

Observed behavior

A regression appears to have been introduced between nats-server v2.10.25 and v2.10.26 that affects how FilterSubjects are handled for consumers configured with DeliverPolicy: DeliverAllPolicy and ReplayPolicy: ReplayInstantPolicy.

When a consumer uses FilterSubjects containing both an exact subject and a related wildcard (e.g., ["stream.A", "stream.A.>"]), it often fails to receive the expected historical messages from the stream upon startup if and only if there are no messages currently in the stream matching the wildcard filter (stream.A.>) at the time the consumer starts.

If at least one message matching the wildcard filter (e.g., stream.A.child) exists in the stream before the consumer starts, the consumer behaves correctly and receives the full history for both filters. If only messages matching the exact subject (stream.A) exist, the bug manifests, and historical messages are often not delivered.

Newly published messages matching the filters are received correctly after startup, regardless of the initial state.

This behavior is inconsistent when the bug manifests; occasionally (though rarely), the consumer does receive the full history even without pre-existing wildcard matches, making it difficult to reliably reproduce without controlling the stream state precisely.

Configuration

  • Stream: Configured with a LimitsPolicy (or other policy) to retain messages. The stream captures subjects matching stream.>. Subjects like stream.A and stream.A.child are published to it.
  • Consumer:
    • DeliverPolicy: DeliverAllPolicy
    • ReplayPolicy: ReplayInstantPolicy
    • AckPolicy: AckExplicitPolicy (or potentially others)
    • FilterSubjects: ["stream.A", "stream.A.>"] (Problematic case)

Observed Behavior

  • Condition: No messages matching stream.A.> exist in the stream. Only messages matching stream.A exist.
    • With FilterSubjects: ["stream.A", "stream.A.>"]:
      • Most of the time, the consumer starts but receives zero historical messages. It only receives new messages published after it started.
      • Occasionally, the consumer starts and correctly receives the full history matching stream.A.
  • Condition: At least one message matching stream.A.> (e.g., stream.A.child) exists in the stream (along with messages matching stream.A).
    • With FilterSubjects: ["stream.A", "stream.A.>"]:
      • The consumer reliably starts and receives the full history matching both stream.A and stream.A.> instantly, as expected.
  • With FilterSubjects: ["stream.A"] (regardless of stream content):
    • The consumer reliably starts and receives the full history matching stream.A instantly, as expected.

Versions

This issue was reproduced locally by testing various nats-server versions:

  • v2.10.25: Works as expected (full history delivered reliably regardless of initial stream content).
  • v2.10.26: Exhibits the bug under the conditions described above.
  • v2.10.27 - v2.11.x: Also exhibit the bug under the conditions described above.

This strongly suggests a change introduced between v2.10.25 and v2.10.26 is responsible.

Expected behavior

When a consumer starts with DeliverAllPolicy, ReplayInstantPolicy, and FilterSubjects: ["stream.A", "stream.A.>"], it should reliably receive all historical messages present in the stream whose subjects match either stream.A or stream.A.>, regardless of whether messages matching stream.A.> were present at the exact moment the consumer started.

Server and client version

nats-server  v2.10.26+
nats.go      v1.39.1

Host environment

Issue first detected from inconsistencies in k8s (via nats helm chart) after v2.11 upgrade from v2.10.25

Replicated locally on Apple MacBook Pro M4

Steps to reproduce

  1. Set up nats-server (v2.10.26 or later).
  2. Create a stream e.g. mystream configured to retain messages on disk and capture subjects matching stream.>.
  3. Scenario A (Bug Manifests):
    • Publish several messages, only with subject stream.A. Ensure no messages exist with subject stream.A.child (or any other subject matching stream.A.>).
    • Create and run a consumer application connecting to mystream with:
      • DeliverPolicy: DeliverAllPolicy
      • ReplayPolicy: ReplayInstantPolicy
      • FilterSubjects: ["stream.A", "stream.A.>"]
    • Observe that the consumer often fails to log the historical stream.A messages immediately upon startup. Repeat consumer startup multiple times to observe inconsistency.
  4. Scenario B (Works Correctly):
    • Publish several messages with subject stream.A.
    • Publish at least one message with subject stream.A.child.
    • Create and run the same consumer application as in Step 3b.
    • Observe that the consumer now reliably logs all historical messages (stream.A and stream.A.child) immediately upon startup.
  5. Verification: Modify the consumer to use FilterSubjects: ["stream.A"] and repeat Scenario A (Step 3a). Observe that history for stream.A is now delivered reliably even without stream.A.child messages present.
  6. Regression Check: Optionally, downgrade nats-server to v2.10.25 and repeat Scenario A (Step 3a) with the original FilterSubjects: ["stream.A", "stream.A.>"] to confirm it works correctly even without pre-existing stream.A.child messages.

Metadata

Metadata

Labels

defectSuspected defect such as a bug or regression

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions