Skip to content

Support native DLQ to be used automatically for failures#1377

Merged
andreasohlund merged 13 commits intodlq-improvementsfrom
dlq-improvements-spikes
Apr 14, 2026
Merged

Support native DLQ to be used automatically for failures#1377
andreasohlund merged 13 commits intodlq-improvementsfrom
dlq-improvements-spikes

Conversation

@andreasohlund
Copy link
Copy Markdown
Member

@andreasohlund andreasohlund commented Apr 11, 2026

This branch introduces an option to change the normal NServiceBus failure
path from MoveToError to native Azure Service Bus dead-lettering.

NOTE: All NServiceBus fault metadata is preserved

@andreasohlund
Copy link
Copy Markdown
Member Author

@danielmarbach @DavidBoike I had a chat with @ramonsmits, and he brought up the idea of always using the DLQ for all failures, since that is the more efficient way to do things. Since we apply all faults metadata, this would be fully equivalent to the default way of "sending to the error queue", with the only difference that the DLQ source, reason, and description would also be set.

Thoughts?

Comment thread src/Tests/ApprovalFiles/APIApprovals.Approve.approved.txt
Comment thread src/Transport/Receiving/MessageExtensions.cs
Comment thread src/AcceptanceTests/When_dlq_use_for_failures_enabled.cs Outdated
@andreasohlund
Copy link
Copy Markdown
Member Author

I looked into what MT and Wolverine do in this area:

MT

By default, MassTransit moves faulted messages to its _error queue, but on Azure Service Bus it can be
configured to move faulted messages to the native ASB DLQ instead, while still generating
fault events. It also has ConfigureDeadLetterQueueDeadLetterTransport() for skipped messages
to use the native DLQ instead of _skipped.

Wolverine

Wolverine uses the native ASB DLQ only for inline endpoints. For buffered and
durable endpoints, failed messages go to a separate dead-letter queue (default
wolverine-dead-letter-queue, configurable with ConfigureDeadLetterQueue(...)) rather than the
ASB subqueue.

@andreasohlund
Copy link
Copy Markdown
Member Author

This does unlock use of the azure portal for rudimentatry error management

image

@andreasohlund andreasohlund marked this pull request as ready for review April 14, 2026 12:11
@andreasohlund
Copy link
Copy Markdown
Member Author

@ramonsmits spoke to @danielmarbach, and we believe this is the middle ground for now, where dlq auto forwarding on created queues is a separate feature from "move all fault to the error queue"

@andreasohlund andreasohlund merged commit 21dd4d6 into dlq-improvements Apr 14, 2026
4 checks passed
@andreasohlund andreasohlund deleted the dlq-improvements-spikes branch April 14, 2026 12:24
danielmarbach pushed a commit that referenced this pull request Apr 15, 2026
* Support native DLQ to be used automatically for failures

* Cleanup

* Fix validation

* Remove unused ctor

* comment

* Use is

* Provide API via recoverability config

* Revert

* Approvals

* Spelling

* Move file

* Wording

* Better name
@udidahan
Copy link
Copy Markdown
Member

If users make use of this, does that mean that they can no longer manage/retry those failed messages through ServicePulse/Control?

@andreasohlund
Copy link
Copy Markdown
Member Author

@udidahan ServiceControl can and should still be used ( see https://github.com/Particular/NServiceBus.Transport.AzureServiceBus/pull/1373/changes#diff-decced24b3ffe2c2e4693fa12eda01ec063149f6b3c5a763c99f0346765f8e9cR16 which shows this flow (errorspy would be equivalent to SC)

The scenario that would be recommended is the following:

  1. Automatic DLQ forwarding is turned on for all endpoints: This means that all DLQ messages will end up in the central error queue
  2. (Optionally) turn this feature on since it would be more performant and result in slightly lower costs for the user, since there wouldn't be a "copy and send" operation to get messages into the error queue, but rather a "native reject and DLQ" which is assumed to be more efficient
  3. Manage errors centrally in ServicePulse

This means that no matter if the service bus service itself (e.g., due to max delivery count being met), NServiceBus (due to e.g., headers being corrupted), or the user themselves causes a message to be dead lettered, all failures would be manageable via the Platform (unlike today, where dlq's are up to the users to manage separately)

@danielmarbach
Copy link
Copy Markdown
Contributor

I would even add it makes the platform more useful

danielmarbach pushed a commit that referenced this pull request Apr 20, 2026
* Allow users to request dead lettering

* Move files

* Consolidate

* Simplify

* Add support for additional properties in dead letter requests

* Add support for setting up DLQ forwarding on receive queues

* Make sure we strip out the qualifier

* Add support for namspace hierarchy

* Revert signing

* Approval

* Add roundtrip acceptance test

* Better name

* Add unit tests for deadletter request

* Upconvert DLQ details to nsb failed headers

* Add option to create dlq forwarding to the command line tool

* Tweaks

* Clarify

* Fix bug

* Apply suggestion from @andreasohlund

* Cleanup

* Fix big

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/Transport/AzureServiceBusTransport.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Typo

* dispose

* Support native DLQ to be used automatically for failures (#1377)

* Support native DLQ to be used automatically for failures

* Cleanup

* Fix validation

* Remove unused ctor

* comment

* Use is

* Provide API via recoverability config

* Revert

* Approvals

* Spelling

* Move file

* Wording

* Better name

* Cleanup test

* Formatting

* Change exception type for invalid dead lettering in None transaction mode

* Make queue creation code more explicit and add comments to explain assumptions

* Refactor assertions in CommandLineTests to use Is.Zero and Is.Empty for clarity

* Add remarks to DeadLetterRequest class to clarify usage scenarios

* Update DeadLetterRequest to use IDictionary for properties modification

* Enhance dead letter handling with improved logging and transaction mode checks

* Refactor error handling in MessagePump to streamline transaction usage and improve clarity

* Fix comment in MessagePump to clarify message completion behavior

* Refactor error handling in MessagePump to improve dead letter processing and enhance logging details

* Add ... when truncating

* Refactor dead letter header assignment to prevent overwriting existing values

* Add test for requesting dlq in tx mode none

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@udidahan
Copy link
Copy Markdown
Member

Is there some documentation that would be worth updating with this information?
Other customer communication?

@andreasohlund
Copy link
Copy Markdown
Member Author

Is there some documentation that would be worth updating with this information?
Other customer communication?

Definitely, we are working on the docs, I will ping you FYI once the PR is ready for final review

We'll talk internally about some dedicated communcation as well

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants