Describe the bug
A NATS JetStream source can ingest duplicate rows when one logical source is expanded into multiple actor-owned synthetic splits even though ACK progress is tracked by a single durable consumer cursor.
This happens when parallelism is >=2 and we have more than 1 views attached to a single source.
Error message/log
JetStream consumer state showed ack_floor stuck at 0 while num_redelivered increased, and RisingWave source tables accumulated duplicate rows for the same message key/time.
To Reproduce
First create a NATS-backed source with a minimal JSON payload containing a single property, for example:
CREATE TABLE nats_values (
value INT
) APPEND ONLY WITH (
connector = 'nats',
server_url = 'nats://127.0.0.1:4222',
subject = 'values.demo',
stream = 'values-demo',
consumer.durable_name = 'values-demo-durable'
) FORMAT PLAIN ENCODE JSON;
Then publish messages like:
When the source runs with multiple actors for the same logical source, JetStream may repeatedly redeliver the same earliest unacked messages and RisingWave may ingest duplicates of the same { "value": 1 } payload. When parallelism is >1 and there are more than 1 views chained after a single source.
Expected behavior
I expected one stored JetStream message like { "value": 1 } to be ingested once per delivery attempt after checkpoint-safe ACK progression.
Instead, the same message can be redelivered and appended multiple times because multiple actor-owned synthetic splits contend on one durable consumer cursor.
How did you deploy RisingWave?
Generic local/dev deployment against a JetStream-enabled NATS instance.
The version of RisingWave
Observed on current main before the fix in PR #25680.
Additional context
The simplified root cause is a split-model mismatch:
- meta treated NATS as an adaptive-split source and expanded one discovered split per actor
- the NATS connector delegated progress to a single JetStream durable consumer instead of maintaining independent per-split offsets in RisingWave state
- this let multiple actors interfere with ACK progress on one durable consumer and triggered repeated redelivery
Describe the bug
A NATS JetStream source can ingest duplicate rows when one logical source is expanded into multiple actor-owned synthetic splits even though ACK progress is tracked by a single durable consumer cursor.
This happens when parallelism is >=2 and we have more than 1 views attached to a single source.
Error message/log
To Reproduce
First create a NATS-backed source with a minimal JSON payload containing a single property, for example:
Then publish messages like:
{"value":1}When the source runs with multiple actors for the same logical source, JetStream may repeatedly redeliver the same earliest unacked messages and RisingWave may ingest duplicates of the same
{ "value": 1 }payload. When parallelism is >1 and there are more than 1 views chained after a single source.Expected behavior
I expected one stored JetStream message like
{ "value": 1 }to be ingested once per delivery attempt after checkpoint-safe ACK progression.Instead, the same message can be redelivered and appended multiple times because multiple actor-owned synthetic splits contend on one durable consumer cursor.
How did you deploy RisingWave?
Generic local/dev deployment against a JetStream-enabled NATS instance.
The version of RisingWave
Observed on current main before the fix in PR #25680.
Additional context
The simplified root cause is a split-model mismatch: