Automatic Message Payload Preservation in DLQ Stream #7590
Replies: 3 comments 4 replies
|
We have considered this before but has quite a lot of user feeedback that this is a bad idea due to the payloads potentially being sensitive and DLQ advisories going to different locations outside of nats it might be something that would make sense as a pre stream opt in though |
|
@Atanusaha143 , @ripienaar As far as I can tell, this works with v2.12.4 and R1 streams. With R3, messages might get lost (I am about to create an issues for that). |
|
This is NATS rather than Kafka, but the operational problem is very familiar: a DLQ is only useful if operators can inspect the failed payload, retain provenance, decide whether it is safe to retry, and replay it with an audit trail. ReplayGuard is tackling that control-layer workflow for Kafka. The payload/headers/metadata preservation you describe is especially close to how we think about recoverable provenance. |
Uh oh!
There was an error while loading. Please reload this page.
Problem Statement
When a message reaches its maximum delivery attempts in JetStream, only an advisory message with metadata is sent to the DLQ stream. The original message payload is lost because it gets removed from the source stream after hitting
max_deliver. This makes it impossible to:Currently, there's no built-in JetStream configuration to automatically preserve message payloads in a DLQ when max deliveries is reached.
Current DLQ Stream Configuration
Current DLQ Message Content
When retrieving a message from the DLQ stream by sequence number:
Response:
{ "subject": "$JS.EVENT.ADVISORY.CONSUMER.MAX_DELIVERIES.booking_stream.booking_consumer", "seq": 1, "data": "eyJ0eXBlIjoiaW8ubmF0cy5qZXRzdHJlYW0uYWR2aXNvcnkudjEubWF4X2RlbGl2ZXIiLCJpZCI6IlVDV1J1bHM0aWFENXhDT0NoV2c4anUiLCJ0aW1lc3RhbXAiOiIyMDI1LTExLTE0VDA3OjAzOjUxLjg2MTExMzY3OFoiLCJzdHJlYW0iOiJkZXZfc2JfcmVmdW5kX2Jvb2tpbmdfc3RyZWFtIiwiY29uc3VtZXIiOiJkZXZfc2JfcmVmdW5kX2Jvb2tpbmdfY29uc3VtZXIiLCJzdHJlYW1fc2VxIjoxMCwiZGVsaXZlcmllcyI6NX0=", "time": "2025-11-14T07:03:51.862562668Z" }Decoded advisory data:
{ "type": "io.nats.jetstream.advisory.v1.max_deliver", "id": "UCWRuls4iaD5xCOChWg8ju", "timestamp": "2025-11-14T07:03:51.861113678Z", "stream": "booking_stream", "consumer": "booking_consumer", "stream_seq": 10, "deliveries": 5 }Issue: The advisory only contains metadata (sequence number, delivery count, timestamp) but no original message payload.
Attempting to Retrieve Original Message
According to the documentation:
However, attempting to retrieve the original message fails:
Why? The original message at sequence 10 was removed from the source stream after hitting max deliveries. The documentation assumes the stream retains messages after max deliveries, which is not the default behavior.
How to Get Original Message (Current Workarounds)
Currently, the only way to preserve message payloads in a DLQ is through application-level implementation:
Proposed Feature Request
Add a consumer configuration option to automatically republish messages (including payload) to a DLQ stream when max deliveries is reached:
Option 1: Consumer Configuration
Option 2: Consumer Config YAML
Expected Behavior
Benefits
Related Discussions
Environment
All reactions