Repository navigation
GH-5055 Dead letter outgoing envelopes a transport cannot map - #5185
Merged
Merged
Conversation
… of reporting them sent - Azure Service Bus: an envelope whose mapping throws is reported through MarkSerializationFailureAsync and left out of what is reported sent (the success path used to report the whole original batch) - SNS: mapping failures are reported as serialization failures, not successes; a chunk with nothing mappable is not published. Under ServerlessWithOutbox the durability pass now counts them as OutgoingDeadLettered, not OutgoingSent - Kafka: only the unmappable envelope is a serialization failure; it used to take the whole batch down with it - SendingAgent.MarkSerializationFailureAsync moves the envelopes to dead letter storage when the application has a message store (every mode). The durable agent deletes the outbox row once the dead letter is written, and leaves it for a later sweep when that write fails - The ServerlessWithOutbox single-envelope inline send dead letters an unsendable envelope right away, consistent with the grouped inline send and the durability pass (GH-5047) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DCggXgxnG3EBXoR9rrq37U
Merged
This was referenced Oct 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
When a transport cannot map an outgoing envelope to its broker message, the envelope now goes to dead letter storage. It used to be logged and then deleted as if it had been sent.
AzureServiceBusSenderProtocol): an unmappable envelope is reported throughMarkSerializationFailureAsync. Only the envelopes that were really sent are reported successful. Before this, the success path reported the whole original batch. Covers both the plain and the partitioned send paths.SnsSenderProtocol): mapping failures are reported as serialization failures, not as successes. A chunk where nothing could be mapped is not published at all. UnderServerlessWithOutbox, the durability pass now counts these envelopes asOutgoingDeadLetteredinstead ofOutgoingSent.KafkaSenderProtocol): only the envelope that fails to map is reported as a serialization failure. Before, one bad envelope reported the whole batch, so the envelopes that mapped fine were dropped too. The protocol also gets an internal logger so the original exception is logged.SendingAgent.MarkSerializationFailureAsyncnow moves the envelopes to dead letter storage whenever the application has a message store, in every durability mode. With no runtime or aNullMessageStore, it only logs, as before.DurableSendingAgentdeletes the outbox row once the dead letter is written (Amazon SQS: an oversized message is retried forever, and there is no built-in way to send one #3926 behaviour is kept). If the dead letter write fails, the row stays for a later recovery sweep, so nothing is lost.DurableSendingAgent.sendInlineAsync): an unsendable envelope is dead lettered right away. This matches the grouped inline send and the durability pass (ServerlessWithOutbox: a row the broker refuses as a serialization failure is re-sent by every durability pass #5047).There is no public API change. The new members are internal:
MoveUnsendableToDeadLetterStorageAsync,UnsendableEnvelopeExceptionandKafkaSenderProtocol.Logger.Survey of the other transports
SendAsyncand goes down the agent's retry path, so nothing is dropped. No change.MarkProcessingFailureAsync, which means a retry. Nothing is dropped silently, so these were left alone. They retry rather than dead letter, though, and for Redis and MQTT an unmappable envelope keeps failing everything after it in the batch.Tests run locally (net9.0, Release)
unmappable_outgoing_envelopes_are_dead_lettered_5055plus the Amazon SQS: an oversized message is retried forever, and there is no built-in way to send one #3926 and ServerlessWithOutbox: a row the broker refuses as a serialization failure is re-sent by every durability pass #5047 classes: 12/12.*SendingAgent*,*sending_agent*,*serverless*,*inline_send*,*BatchedSender*,*Durability*): 182/182.unmappable_envelopes_are_reported_as_serialization_failures_5055(batch of three with one unmappable, plain and partitioned) plus the 5044 and message-too-large classes: 10/10. These use a fakedServiceBusSender; the emulator was not used.unmappable_envelopes_are_dead_lettered_5055(Balanced mode, 2 delivered and 1 dead letter row) plusserverless_with_outbox_sns_5044(durability pass:OutgoingSent = 2,OutgoingDeadLettered = 1; also the new inline send case),OutgoingSnsBatchTestsand the 3793 class: 15/15.Closes #5055
🤖 Generated with Claude Code
https://claude.ai/code/session_01DCggXgxnG3EBXoR9rrq37U