From 93d05a489d2d8e57185a575b1614eff8ec17370a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Mon, 20 Apr 2026 16:37:03 +0200 Subject: [PATCH 01/13] First draft --- transports/azure-service-bus/configuration.md | 2 + ...ration_dead-lettering_asbs_[6,).partial.md | 91 +++++++++++++++++++ ...ation_entity-settings_asbs_[6,).partial.md | 1 + ...ting_endpoint-command_asbs_[6,).partial.md | 3 + ...al-scripting_examples_asbs_[5,).partial.md | 44 ++++++--- ...tion-endpoint-command_asbs_[6,).partial.md | 3 + ...ripting_queue-command_asbs_[6,).partial.md | 5 + 7 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md diff --git a/transports/azure-service-bus/configuration.md b/transports/azure-service-bus/configuration.md index 18785ec4a6d..8d71b589d55 100644 --- a/transports/azure-service-bus/configuration.md +++ b/transports/azure-service-bus/configuration.md @@ -73,3 +73,5 @@ partial: lockrenewal > > - Optimise the message handlers to reduce their execution time. > - Reduce the prefetch count. All messages are locked on peek, so when they are prefetched, they remain locked until they are all processed. + +partial: dead-lettering diff --git a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md new file mode 100644 index 00000000000..6b4ef7428b9 --- /dev/null +++ b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md @@ -0,0 +1,91 @@ +### Dead lettering + +Azure Service Bus provides a native dead-letter queue (DLQ) for each queue and subscription. NServiceBus can integrate with this mechanism, allowing failed messages to be dead-lettered natively and forwarded to the central NServiceBus error queue. + +For background information on Azure Service Bus dead-letter queues, see [Overview of Service Bus dead-letter queues](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dead-letter-queues). + +#### Forward dead-lettered messages to the error queue + +When queues are created by the transport, native dead-lettered messages can be auto-forwarded to the configured error queue: + +```csharp +var transport = new AzureServiceBusTransport("", TopicTopology.Default) +{ + AutoForwardDeadLetteredMessagesToErrorQueue = true +}; +``` + +This setting is opt-in and affects only entities created by the transport. See the [`asb-transport` provisioning commands](/transports/azure-service-bus/operational-scripting.md) for more details on scripting options. + +#### Route all failed messages to the native DLQ + +To route failed messages to the native Azure Service Bus dead-letter queue instead of the NServiceBus error queue, enable: + +```csharp +var recoverability = endpointConfiguration.Recoverability(); +recoverability.MoveErrorsToAzureServiceBusDeadLetterQueue(); +``` + +#### Request dead lettering from recoverability + +Use a [custom recoverability policy](/nservicebus/recoverability/custom-recoverability-policy.md) to explicitly request dead lettering for selected failures. + +Dead-letter with standard NServiceBus fault metadata: + +```csharp +endpointConfiguration.Recoverability() + .CustomPolicy((config, errorContext) => + { + if (errorContext.Exception is PoisonMessageException) + { + return RecoverabilityAction.DeadLetter(); + } + + return DefaultRecoverabilityPolicy.Invoke(config, errorContext); + }); +``` + +Dead-letter with custom reason, description, and modified application properties: + +> [!NOTE] +> Using this option does note automatically add the NServiceBus faults metadata to the application properties. + +```csharp +endpointConfiguration.Recoverability() + .CustomPolicy((config, errorContext) => + { + if (errorContext.Exception is MyBusinessException ex) + { + return RecoverabilityAction.DeadLetter( + deadLetterReason: "Business rule validation failed", + deadLetterErrorDescription: ex.Message, + propertiesToModify: new Dictionary + { + ["FailureCategory"] = "Validation" + }); + } + + return DefaultRecoverabilityPolicy.Invoke(config, errorContext); + }); +``` + +#### Fault header mapping + +When processing dead-lettered messages, the transport maps native dead-letter properties to [error forwarding headers](/nservicebus/messaging/headers.md#error-forwarding-headers) when those headers are not already present: + +- `DeadLetterSource` -> `NServiceBus.FailedQ` +- `DeadLetterReason` -> `NServiceBus.ExceptionInfo.Message` +- `DeadLetterErrorDescription` -> `NServiceBus.ExceptionInfo.StackTrace` + +This mapping helps tools such as ServiceControl and ServicePulse present failure information consistently. + +#### Monitoring and operations + +[ServicePulse failed message monitoring](/servicepulse/intro-failed-messages.md) tracks messages in the NServiceBus error queue. If endpoint failures are kept in native Azure Service Bus dead-letter queues without forwarding, those failures require Azure-native operational tooling. + +Enable dlq forwarding described above when you want native dead lettering and centralized failed-message handling together. + +#### Caveats + +- `TransportTransactionMode.None` uses receive-and-delete semantics, so dead-lettering actions cannot be performed in that mode. See [transport transactions](/transports/transactions.md#transaction-modes-unreliable-transactions-disabled). +- The transport truncates dead-letter reason and description to 1024 characters to reduce oversized message risk. Review Azure limits in [Service Bus quotas](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quotas). diff --git a/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md index 6d7c6d2b2a4..877630864fd 100644 --- a/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md @@ -3,4 +3,5 @@ * `EntityMaximumSize`: The maximum entity size in GB. The value must correspond to a valid value for the namespace type. Defaults to 5. See [the Microsoft documentation on quotas and limits](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quotas) for valid values. * `EnablePartitioning`: Partitioned entities offer higher availability, reliability, and throughput over conventional non-partitioned queues and topics. For more information about partitioned entities [see the Microsoft documentation on partitioned messaging entities](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-partitioning). * `AutoDeleteOnIdle`: A `TimeSpan` representing the [AutoDeleteOnIdle](https://learn.microsoft.com/en-us/azure/service-bus-messaging/advanced-features-overview#autodelete-on-idle) setting for instance-specific input queues (such as when using [`MakeInstanceUniquelyAddressable`](/nservicebus/messaging/routing.md#make-instance-uniquely-addressable)) created by the transport. This value is the maximum time period that a queue can remain [idle](https://learn.microsoft.com/en-us/azure/service-bus-messaging/message-expiration#idleness) before Azure Service Bus automatically deletes it. Defaults to `TimeSpan.MaxValue` in Azure Service Bus if this setting is not specified within the transport. The minimum allowed value is 5 minutes. The transport will not apply this setting to topics or subscriptions as these are considered shared infrastructure (along with shared queues such as error and audit). +* `AutoForwardDeadLetteredMessagesToErrorQueue`: When enabled, dead-lettered messages from transport-created receive queues are auto-forwarded to the configured NServiceBus error queue. It's recommended to enable this option to centralize failed-message handling for dead-letter queues. For general Azure Service Bus forwarding behavior, see [Enable auto forwarding for Azure Service Bus queues and subscriptions](https://learn.microsoft.com/en-us/azure/service-bus-messaging/enable-auto-forward). * `HierarchyNamespaceOptions`: Beginning version 6.1, [hierarchical entities](https://learn.microsoft.com/en-us/rest/api/servicebus/addressing-and-protocol) can be [configured using a hierarchical namespace](#entity-creation-hierarchy-namespace). Setting this with the required `HierarchyNamespace` property will prefix all entity paths in the format `{HierarchyNamespace}/{original-entity-path}`. Defaults to `HierarchyNamespaceOptions.None`, which disables prefixing with a hierarchy namespace. diff --git a/transports/azure-service-bus/operational-scripting_endpoint-command_asbs_[6,).partial.md b/transports/azure-service-bus/operational-scripting_endpoint-command_asbs_[6,).partial.md index 0dd5b7cc42c..d00040b93b7 100644 --- a/transports/azure-service-bus/operational-scripting_endpoint-command_asbs_[6,).partial.md +++ b/transports/azure-service-bus/operational-scripting_endpoint-command_asbs_[6,).partial.md @@ -6,6 +6,7 @@ Creates infrastructure for an endpoint -- input queue. asb-transport endpoint create name [--size] [--partitioned] + [--forward-dlq-to] ``` #### options @@ -20,6 +21,8 @@ asb-transport endpoint create name `-h` | `--hierarchy-namespace`: Sets the hierarchy namespace for prefixing destinations in the format `/` (available from version 6.1) +`-f` | `--forward-dlq-to`: Queue name to auto-forward dead-lettered messages to. The queue will be created if it does not exist. The resolved queue name cannot be the same as the endpoint queue. + ### asb-transport endpoint subscribe Creates a new subscription for an endpoint. diff --git a/transports/azure-service-bus/operational-scripting_examples_asbs_[5,).partial.md b/transports/azure-service-bus/operational-scripting_examples_asbs_[5,).partial.md index 596e7e470ef..9684c8c32d0 100644 --- a/transports/azure-service-bus/operational-scripting_examples_asbs_[5,).partial.md +++ b/transports/azure-service-bus/operational-scripting_examples_asbs_[5,).partial.md @@ -2,21 +2,33 @@ Create the topology for an endpoint named `MyEndpoint`: -``` +```txt asb-transport endpoint create MyEndpoint -c "" ``` -### Subscribing to events +Create the topology for an endpoint named `MyEndpoint` and forward dead-lettered messages to the `error` queue: -Subscribe `MyOtherEndpoint` to the event `Contracts.Events.SomeEvent` using the default settings: +```txt +asb-transport endpoint create MyEndpoint --forward-dlq-to error -c "" +``` + +Create a queue and configure dead-letter forwarding to the `error` queue: +```txt +asb-transport queue create MyEndpoint --forward-dlq-to error -c "" ``` + +### Subscribing to events (migration topology) + +Subscribe `MyOtherEndpoint` to the event `Contracts.Events.SomeEvent` using the default settings: + +```txt asb-transport endpoint subscribe MyOtherEndpoint Contracts.Events.SomeEvent -c "" ``` Subscribe `MyOtherEndpoint` to the event `Contracts.Events.SomeEvent` and override the subscription name to be `my-other-endpoint` -``` +```txt asb-transport endpoint subscribe MyOtherEndpoint Contracts.Events.SomeEvent -s my-other-endpoint -c "" ``` @@ -24,19 +36,25 @@ asb-transport endpoint subscribe MyOtherEndpoint Contracts.Events.SomeEvent -s m Create the topology for an endpoint named `MyEndpoint` using the default settings: -``` +```txt asb-transport migration endpoint create MyEndpoint -c "" ``` -Create the topology for an endpoint named `MyEndpoint` and override the topic name to be `custom-topic` and the subscription name to be `my-endpoint`: +Create migration topology and forward dead-lettered messages to the `error` queue: +```txt +asb-transport migration endpoint create MyEndpoint --forward-dlq-to error -c "" ``` + +Create the topology for an endpoint named `MyEndpoint` and override the topic name to be `custom-topic` and the subscription name to be `my-endpoint`: + +```txt asb-transport migration endpoint create MyEndpoint -t custom-topic -s my-endpoint -c "" ``` Create the topology for an endpoint named `MyEndpoint` and override the publish topic name to be `custom-publish-topic` and the subscription topic name to be `custom-subscribe-topic`: -``` +```txt asb-transport migration endpoint create MyEndpoint -tp custom-publish-topic -ts custom-subscribe-topic -c "" ``` @@ -44,30 +62,30 @@ asb-transport migration endpoint create MyEndpoint -tp custom-publish-topic -ts Subscribe `MyOtherEndpoint` to the event `Contracts.Events.SomeEvent` using the default settings: -``` +```txt asb-transport migration endpoint subscribe MyOtherEndpoint Contracts.Events.SomeEvent -c "" ``` Subscribe `MyOtherEndpoint` to the event `Contracts.Events.SomeEvent` using the topic-per-event apprach (after migration): -``` +```txt asb-transport migration endpoint subscribe-migrated MyOtherEndpoint Contracts.Events.SomeEvent -c "" ``` Subscribe `MyOtherEndpoint` to the event `Contracts.Events.SomeEvent` and override the topic name to be `custom-topic`: -``` +```txt asb-transport migration endpoint subscribe MyOtherEndpoint Contracts.Events.SomeEvent -t custom-topic -c "" ``` Subscribe `MyOtherEndpoint` to the event `Contracts.Events.SomeEvent` and override the subscription name to be `my-other-endpoint` -``` +```txt asb-transport migration endpoint subscribe MyOtherEndpoint Contracts.Events.SomeEvent -s my-other-endpoint -c "" ``` Subscribe `MyOtherEndpoint` to the event `Contracts.Events.SomeEvent` and override the subscription rule name to be `SomeEvent`: -``` +```txt asb-transport migration endpoint subscribe MyOtherEndpoint Contracts.Events.SomeEvent -r SomeEvent -c "" -``` \ No newline at end of file +``` diff --git a/transports/azure-service-bus/operational-scripting_migration-endpoint-command_asbs_[6,).partial.md b/transports/azure-service-bus/operational-scripting_migration-endpoint-command_asbs_[6,).partial.md index 80969fa9198..ea2602d0b9b 100644 --- a/transports/azure-service-bus/operational-scripting_migration-endpoint-command_asbs_[6,).partial.md +++ b/transports/azure-service-bus/operational-scripting_migration-endpoint-command_asbs_[6,).partial.md @@ -19,6 +19,7 @@ asb-transport migration endpoint create name [--topic] [--topic-to-publish-to] [--topic-to-subscribe-on] [--subscription] + [--forward-dlq-to] ``` #### options @@ -41,6 +42,8 @@ asb-transport migration endpoint create name `-h` | `--hierarchy-namespace`: Sets the hierarchy namespace for prefixing destinations in the format `/` (available from version 6.1) +`-f` | `--forward-dlq-to`: Queue name to auto-forward dead-lettered messages to. The queue will be created if it does not exist. The resolved queue name cannot be the same as the endpoint queue. + > [!NOTE] > The hierarchy namespace option shifts the migration endpoint consistently into the hierarchy meaning the endpoint name and topics will have the hierarchy name applied. diff --git a/transports/azure-service-bus/operational-scripting_queue-command_asbs_[6,).partial.md b/transports/azure-service-bus/operational-scripting_queue-command_asbs_[6,).partial.md index 12eb2aa63f9..7a852ad504d 100644 --- a/transports/azure-service-bus/operational-scripting_queue-command_asbs_[6,).partial.md +++ b/transports/azure-service-bus/operational-scripting_queue-command_asbs_[6,).partial.md @@ -6,6 +6,7 @@ Create a queue using: asb-transport queue create name [--size] [--partitioned] + [--forward-dlq-to] ``` #### options @@ -20,6 +21,10 @@ asb-transport queue create name `-h` | `--hierarchy-namespace`: Sets the hierarchy namespace for prefixing destinations in the format `/` (available from version 6.1) +`-f` | `--forward-dlq-to`: Queue name to auto-forward dead-lettered messages to. The queue will be created if it does not exist. The resolved queue name cannot be the same as the source queue. + +See also the Azure CLI option [`--forward-dead-lettered-messages-to`](https://learn.microsoft.com/en-us/cli/azure/servicebus/queue?view=azure-cli-latest#az-servicebus-queue-create). + ### asb-transport queue delete From c40734bc793571625a5a445a4c242ca73ed82d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Mon, 20 Apr 2026 18:56:24 +0200 Subject: [PATCH 02/13] Snippets --- Snippets/ASBS/ASBS_6/ASBS_6.csproj | 2 +- Snippets/ASBS/ASBS_6/DeadLettering.cs | 67 +++++++++++++++++++ Snippets/ASBS/ASBS_6/Usage.cs | 6 +- ...ration_dead-lettering_asbs_[6,).partial.md | 46 ++----------- 4 files changed, 78 insertions(+), 43 deletions(-) create mode 100644 Snippets/ASBS/ASBS_6/DeadLettering.cs diff --git a/Snippets/ASBS/ASBS_6/ASBS_6.csproj b/Snippets/ASBS/ASBS_6/ASBS_6.csproj index f8ee3d00bf5..c5793ea84ad 100644 --- a/Snippets/ASBS/ASBS_6/ASBS_6.csproj +++ b/Snippets/ASBS/ASBS_6/ASBS_6.csproj @@ -5,7 +5,7 @@ - + diff --git a/Snippets/ASBS/ASBS_6/DeadLettering.cs b/Snippets/ASBS/ASBS_6/DeadLettering.cs new file mode 100644 index 00000000000..415f3aff1f9 --- /dev/null +++ b/Snippets/ASBS/ASBS_6/DeadLettering.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using NServiceBus; +using NServiceBus.Transport.AzureServiceBus; + +class DeadLettering +{ + void MoveErrorsToDeadLetterQueue(EndpointConfiguration endpointConfiguration) + { + #region dlq-all-errors + + endpointConfiguration.Recoverability() + .MoveErrorsToAzureServiceBusDeadLetterQueue(); + + #endregion + } + + void ExplicitDlq(EndpointConfiguration endpointConfiguration) + { + #region explicit-dlq + + endpointConfiguration.Recoverability() + .CustomPolicy((config, errorContext) => + { + if (errorContext.Exception is PoisonMessageException) + { + return RecoverabilityAction.DeadLetter(); + } + + return DefaultRecoverabilityPolicy.Invoke(config, errorContext); + }); + + #endregion + } + + void ExplicitDlqFullControl(EndpointConfiguration endpointConfiguration) + { + #region explicit-dlq-full-control + + endpointConfiguration.Recoverability() + .CustomPolicy((config, errorContext) => + { + if (errorContext.Exception is MyBusinessException ex) + { + return RecoverabilityAction.DeadLetter( + deadLetterReason: "Business rule validation failed", + deadLetterErrorDescription: ex.Message, + propertiesToModify: new Dictionary + { + ["FailureCategory"] = "Validation" + }); + } + + return DefaultRecoverabilityPolicy.Invoke(config, errorContext); + + #endregion + }); + } + + class PoisonMessageException : Exception + { + } + + class MyBusinessException : Exception + { + } +} \ No newline at end of file diff --git a/Snippets/ASBS/ASBS_6/Usage.cs b/Snippets/ASBS/ASBS_6/Usage.cs index 1b5ed398c36..52e3a19a3f5 100644 --- a/Snippets/ASBS/ASBS_6/Usage.cs +++ b/Snippets/ASBS/ASBS_6/Usage.cs @@ -146,6 +146,10 @@ class Usage // exclude all types that inherit an interface or base type transport.HierarchyNamespaceOptions.ExcludeMessageType(); #endregion + + #region enable-dlq-auto-forwarding + transport.AutoForwardDeadLetteredMessagesToErrorQueue = true; + #endregion } @@ -155,7 +159,7 @@ public class MyExcludedMessage {} public interface IAmExcludedFromTheHierarchy {} public class MyExcludedMessageByInterface : IAmExcludedFromTheHierarchy { } - + public class MyOtherExcludedMessageByInterface : IAmExcludedFromTheHierarchy {} #endregion class MyEvent; diff --git a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md index 6b4ef7428b9..ad49b0cb402 100644 --- a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md @@ -8,12 +8,7 @@ For background information on Azure Service Bus dead-letter queues, see [Overvie When queues are created by the transport, native dead-lettered messages can be auto-forwarded to the configured error queue: -```csharp -var transport = new AzureServiceBusTransport("", TopicTopology.Default) -{ - AutoForwardDeadLetteredMessagesToErrorQueue = true -}; -``` +snippet: enable-dlq-auto-forwarding This setting is opt-in and affects only entities created by the transport. See the [`asb-transport` provisioning commands](/transports/azure-service-bus/operational-scripting.md) for more details on scripting options. @@ -21,10 +16,7 @@ This setting is opt-in and affects only entities created by the transport. See t To route failed messages to the native Azure Service Bus dead-letter queue instead of the NServiceBus error queue, enable: -```csharp -var recoverability = endpointConfiguration.Recoverability(); -recoverability.MoveErrorsToAzureServiceBusDeadLetterQueue(); -``` +snippet: dlq-all-errors #### Request dead lettering from recoverability @@ -32,42 +24,14 @@ Use a [custom recoverability policy](/nservicebus/recoverability/custom-recovera Dead-letter with standard NServiceBus fault metadata: -```csharp -endpointConfiguration.Recoverability() - .CustomPolicy((config, errorContext) => - { - if (errorContext.Exception is PoisonMessageException) - { - return RecoverabilityAction.DeadLetter(); - } - - return DefaultRecoverabilityPolicy.Invoke(config, errorContext); - }); -``` +snippet: explicit-dlq Dead-letter with custom reason, description, and modified application properties: > [!NOTE] > Using this option does note automatically add the NServiceBus faults metadata to the application properties. -```csharp -endpointConfiguration.Recoverability() - .CustomPolicy((config, errorContext) => - { - if (errorContext.Exception is MyBusinessException ex) - { - return RecoverabilityAction.DeadLetter( - deadLetterReason: "Business rule validation failed", - deadLetterErrorDescription: ex.Message, - propertiesToModify: new Dictionary - { - ["FailureCategory"] = "Validation" - }); - } - - return DefaultRecoverabilityPolicy.Invoke(config, errorContext); - }); -``` +snippet: explicit-dlq-full-control #### Fault header mapping @@ -83,7 +47,7 @@ This mapping helps tools such as ServiceControl and ServicePulse present failure [ServicePulse failed message monitoring](/servicepulse/intro-failed-messages.md) tracks messages in the NServiceBus error queue. If endpoint failures are kept in native Azure Service Bus dead-letter queues without forwarding, those failures require Azure-native operational tooling. -Enable dlq forwarding described above when you want native dead lettering and centralized failed-message handling together. +Enable dlq forwarding as described above when you want to centralized native dead lettering and failed-message handling. #### Caveats From a681769d26a4f75110af6ddc699b69859026d38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Tue, 21 Apr 2026 08:25:22 +0200 Subject: [PATCH 03/13] Add note about v6.3 --- .../configuration_dead-lettering_asbs_[6,).partial.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md index ad49b0cb402..1a631ea2d13 100644 --- a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md @@ -1,5 +1,8 @@ ### Dead lettering +> [!NOTE] +> Support for dead lettering is available in Version 6.3.0 and higher. + Azure Service Bus provides a native dead-letter queue (DLQ) for each queue and subscription. NServiceBus can integrate with this mechanism, allowing failed messages to be dead-lettered natively and forwarded to the central NServiceBus error queue. For background information on Azure Service Bus dead-letter queues, see [Overview of Service Bus dead-letter queues](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dead-letter-queues). From 2e14302c0f24bc81cca86cadbac8deb0a6438290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Tue, 21 Apr 2026 08:27:27 +0200 Subject: [PATCH 04/13] Use level 2 heading --- .../configuration_dead-lettering_asbs_[6,).partial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md index 1a631ea2d13..a2f035efb63 100644 --- a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md @@ -1,4 +1,4 @@ -### Dead lettering +## Dead lettering > [!NOTE] > Support for dead lettering is available in Version 6.3.0 and higher. From 0f14f14d1d68ecead304d2df2431c0c8fbd637a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Tue, 21 Apr 2026 08:29:10 +0200 Subject: [PATCH 05/13] Apply suggestions from code review Co-authored-by: David Boike --- .../configuration_dead-lettering_asbs_[6,).partial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md index a2f035efb63..92058a3cf61 100644 --- a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md @@ -50,7 +50,7 @@ This mapping helps tools such as ServiceControl and ServicePulse present failure [ServicePulse failed message monitoring](/servicepulse/intro-failed-messages.md) tracks messages in the NServiceBus error queue. If endpoint failures are kept in native Azure Service Bus dead-letter queues without forwarding, those failures require Azure-native operational tooling. -Enable dlq forwarding as described above when you want to centralized native dead lettering and failed-message handling. +Enable DLQ forwarding as described above when you want to centralized native dead lettering and failed-message handling. #### Caveats From 9d6fadfd534b2b5f93462bb18feb7d79e3210fe3 Mon Sep 17 00:00:00 2001 From: David Boike Date: Tue, 21 Apr 2026 16:48:08 -0500 Subject: [PATCH 06/13] Update transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md --- .../configuration_dead-lettering_asbs_[6,).partial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md index 92058a3cf61..4a4ff231fc8 100644 --- a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md @@ -13,7 +13,7 @@ When queues are created by the transport, native dead-lettered messages can be a snippet: enable-dlq-auto-forwarding -This setting is opt-in and affects only entities created by the transport. See the [`asb-transport` provisioning commands](/transports/azure-service-bus/operational-scripting.md) for more details on scripting options. +This setting is opt-in and affects only queues created by the transport. See the [`asb-transport` provisioning commands](/transports/azure-service-bus/operational-scripting.md) for more details on scripting options. #### Route all failed messages to the native DLQ From cdbfb84a94317b192326c37556faf97ac52ac388 Mon Sep 17 00:00:00 2001 From: David Boike Date: Tue, 21 Apr 2026 16:49:32 -0500 Subject: [PATCH 07/13] Make H2toH4 into H2toH3 --- ...configuration_dead-lettering_asbs_[6,).partial.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md index 4a4ff231fc8..e2999f4565c 100644 --- a/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_dead-lettering_asbs_[6,).partial.md @@ -7,7 +7,7 @@ Azure Service Bus provides a native dead-letter queue (DLQ) for each queue and s For background information on Azure Service Bus dead-letter queues, see [Overview of Service Bus dead-letter queues](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dead-letter-queues). -#### Forward dead-lettered messages to the error queue +### Forward dead-lettered messages to the error queue When queues are created by the transport, native dead-lettered messages can be auto-forwarded to the configured error queue: @@ -15,13 +15,13 @@ snippet: enable-dlq-auto-forwarding This setting is opt-in and affects only queues created by the transport. See the [`asb-transport` provisioning commands](/transports/azure-service-bus/operational-scripting.md) for more details on scripting options. -#### Route all failed messages to the native DLQ +### Route all failed messages to the native DLQ To route failed messages to the native Azure Service Bus dead-letter queue instead of the NServiceBus error queue, enable: snippet: dlq-all-errors -#### Request dead lettering from recoverability +### Request dead lettering from recoverability Use a [custom recoverability policy](/nservicebus/recoverability/custom-recoverability-policy.md) to explicitly request dead lettering for selected failures. @@ -36,7 +36,7 @@ Dead-letter with custom reason, description, and modified application properties snippet: explicit-dlq-full-control -#### Fault header mapping +### Fault header mapping When processing dead-lettered messages, the transport maps native dead-letter properties to [error forwarding headers](/nservicebus/messaging/headers.md#error-forwarding-headers) when those headers are not already present: @@ -46,13 +46,13 @@ When processing dead-lettered messages, the transport maps native dead-letter pr This mapping helps tools such as ServiceControl and ServicePulse present failure information consistently. -#### Monitoring and operations +### Monitoring and operations [ServicePulse failed message monitoring](/servicepulse/intro-failed-messages.md) tracks messages in the NServiceBus error queue. If endpoint failures are kept in native Azure Service Bus dead-letter queues without forwarding, those failures require Azure-native operational tooling. Enable DLQ forwarding as described above when you want to centralized native dead lettering and failed-message handling. -#### Caveats +### Caveats - `TransportTransactionMode.None` uses receive-and-delete semantics, so dead-lettering actions cannot be performed in that mode. See [transport transactions](/transports/transactions.md#transaction-modes-unreliable-transactions-disabled). - The transport truncates dead-letter reason and description to 1024 characters to reduce oversized message risk. Review Azure limits in [Service Bus quotas](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quotas). From d5896ef52ed7cc85006087d595f3bc1b69946e31 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Fri, 24 Apr 2026 11:37:56 +0200 Subject: [PATCH 08/13] Bump alpha --- Snippets/ASBS/ASBS_6/ASBS_6.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snippets/ASBS/ASBS_6/ASBS_6.csproj b/Snippets/ASBS/ASBS_6/ASBS_6.csproj index c5793ea84ad..7dd77de570e 100644 --- a/Snippets/ASBS/ASBS_6/ASBS_6.csproj +++ b/Snippets/ASBS/ASBS_6/ASBS_6.csproj @@ -5,7 +5,7 @@ - + From 01ca7e179be2098067e6178213edbdec328ab85b Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Fri, 24 Apr 2026 11:51:45 +0200 Subject: [PATCH 09/13] MaxDeliveryCount and ThrowOnMissingTopicWhenPublishing Cover latest addition for AutoForwardDeadLetteredMessagesToErrorQueue --- .../configuration_entity-settings_asbs_[6,).partial.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md index 877630864fd..473be3668a1 100644 --- a/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md @@ -3,5 +3,7 @@ * `EntityMaximumSize`: The maximum entity size in GB. The value must correspond to a valid value for the namespace type. Defaults to 5. See [the Microsoft documentation on quotas and limits](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quotas) for valid values. * `EnablePartitioning`: Partitioned entities offer higher availability, reliability, and throughput over conventional non-partitioned queues and topics. For more information about partitioned entities [see the Microsoft documentation on partitioned messaging entities](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-partitioning). * `AutoDeleteOnIdle`: A `TimeSpan` representing the [AutoDeleteOnIdle](https://learn.microsoft.com/en-us/azure/service-bus-messaging/advanced-features-overview#autodelete-on-idle) setting for instance-specific input queues (such as when using [`MakeInstanceUniquelyAddressable`](/nservicebus/messaging/routing.md#make-instance-uniquely-addressable)) created by the transport. This value is the maximum time period that a queue can remain [idle](https://learn.microsoft.com/en-us/azure/service-bus-messaging/message-expiration#idleness) before Azure Service Bus automatically deletes it. Defaults to `TimeSpan.MaxValue` in Azure Service Bus if this setting is not specified within the transport. The minimum allowed value is 5 minutes. The transport will not apply this setting to topics or subscriptions as these are considered shared infrastructure (along with shared queues such as error and audit). -* `AutoForwardDeadLetteredMessagesToErrorQueue`: When enabled, dead-lettered messages from transport-created receive queues are auto-forwarded to the configured NServiceBus error queue. It's recommended to enable this option to centralize failed-message handling for dead-letter queues. For general Azure Service Bus forwarding behavior, see [Enable auto forwarding for Azure Service Bus queues and subscriptions](https://learn.microsoft.com/en-us/azure/service-bus-messaging/enable-auto-forward). +* `AutoForwardDeadLetteredMessagesToErrorQueue`: When enabled, dead-lettered messages from transport-created receive queues are auto-forwarded to the configured NServiceBus error queue. It's recommended to enable this option to centralize failed-message handling for dead-letter queues. For general Azure Service Bus forwarding behavior, see [Enable auto forwarding for Azure Service Bus queues and subscriptions](https://learn.microsoft.com/en-us/azure/service-bus-messaging/enable-auto-forward). This setting is nullable; when not explicitly configured, a warning is logged at runtime if a message is dead-lettered. * `HierarchyNamespaceOptions`: Beginning version 6.1, [hierarchical entities](https://learn.microsoft.com/en-us/rest/api/servicebus/addressing-and-protocol) can be [configured using a hierarchical namespace](#entity-creation-hierarchy-namespace). Setting this with the required `HierarchyNamespace` property will prefix all entity paths in the format `{HierarchyNamespace}/{original-entity-path}`. Defaults to `HierarchyNamespaceOptions.None`, which disables prefixing with a hierarchy namespace. +* `MaxDeliveryCount`: The maximum delivery count applied to queues created during endpoint infrastructure setup. Defaults to `int.MaxValue`, which effectively disables Azure Service Bus's built-in delivery count limits and defers all retry decisions to NServiceBus recoverability. The Azure Service Bus Emulator requires a value of `10`. When choosing a value, ensure it is high enough to allow the configured recoverability policy to eventually move the message to the error queue, but not so high that it creates effectively infinite retries. +* `ThrowOnMissingTopicWhenPublishing`: When enabled, the transport throws an `InvalidOperationException` when publishing to a non-existent topic. The transport always logs a warning when publishing to a non-existent topic. Defaults to `false` for backward compatibility. From 4226543962746f53f8b8432354513b0fd66c0deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Sun, 26 Apr 2026 08:24:50 +0200 Subject: [PATCH 10/13] Fix region --- Snippets/ASBS/ASBS_6/DeadLettering.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snippets/ASBS/ASBS_6/DeadLettering.cs b/Snippets/ASBS/ASBS_6/DeadLettering.cs index 415f3aff1f9..7b17d6f2850 100644 --- a/Snippets/ASBS/ASBS_6/DeadLettering.cs +++ b/Snippets/ASBS/ASBS_6/DeadLettering.cs @@ -53,8 +53,8 @@ void ExplicitDlqFullControl(EndpointConfiguration endpointConfiguration) return DefaultRecoverabilityPolicy.Invoke(config, errorContext); - #endregion }); + #endregion } class PoisonMessageException : Exception From 6cb8b2a3cd6ce344b937e685b8181abf74c13c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Mon, 4 May 2026 10:46:31 +0200 Subject: [PATCH 11/13] Use stable 6.3.0 --- Snippets/ASBS/ASBS_6/ASBS_6.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snippets/ASBS/ASBS_6/ASBS_6.csproj b/Snippets/ASBS/ASBS_6/ASBS_6.csproj index 7dd77de570e..20ae1123ad8 100644 --- a/Snippets/ASBS/ASBS_6/ASBS_6.csproj +++ b/Snippets/ASBS/ASBS_6/ASBS_6.csproj @@ -5,7 +5,7 @@ - + From 688b6ae1e0c918a0b8d76f48f994510e0bb153e2 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 4 May 2026 10:56:36 +0200 Subject: [PATCH 12/13] Fix documentation --- .../configuration_entity-settings_asbs_[6,).partial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md b/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md index 473be3668a1..bffef8a1800 100644 --- a/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md +++ b/transports/azure-service-bus/configuration_entity-settings_asbs_[6,).partial.md @@ -6,4 +6,4 @@ * `AutoForwardDeadLetteredMessagesToErrorQueue`: When enabled, dead-lettered messages from transport-created receive queues are auto-forwarded to the configured NServiceBus error queue. It's recommended to enable this option to centralize failed-message handling for dead-letter queues. For general Azure Service Bus forwarding behavior, see [Enable auto forwarding for Azure Service Bus queues and subscriptions](https://learn.microsoft.com/en-us/azure/service-bus-messaging/enable-auto-forward). This setting is nullable; when not explicitly configured, a warning is logged at runtime if a message is dead-lettered. * `HierarchyNamespaceOptions`: Beginning version 6.1, [hierarchical entities](https://learn.microsoft.com/en-us/rest/api/servicebus/addressing-and-protocol) can be [configured using a hierarchical namespace](#entity-creation-hierarchy-namespace). Setting this with the required `HierarchyNamespace` property will prefix all entity paths in the format `{HierarchyNamespace}/{original-entity-path}`. Defaults to `HierarchyNamespaceOptions.None`, which disables prefixing with a hierarchy namespace. * `MaxDeliveryCount`: The maximum delivery count applied to queues created during endpoint infrastructure setup. Defaults to `int.MaxValue`, which effectively disables Azure Service Bus's built-in delivery count limits and defers all retry decisions to NServiceBus recoverability. The Azure Service Bus Emulator requires a value of `10`. When choosing a value, ensure it is high enough to allow the configured recoverability policy to eventually move the message to the error queue, but not so high that it creates effectively infinite retries. -* `ThrowOnMissingTopicWhenPublishing`: When enabled, the transport throws an `InvalidOperationException` when publishing to a non-existent topic. The transport always logs a warning when publishing to a non-existent topic. Defaults to `false` for backward compatibility. +* `ThrowOnMissingTopicWhenPublishing`: When enabled, the transport re-throws the underlying `ServiceBusException` when publishing to a non-existent topic. The transport always logs a warning when publishing to a non-existent topic. Defaults to `false` for backward compatibility. From 399ff4bba819fac4935ce1af2011bbf5124ae308 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 4 May 2026 10:57:18 +0200 Subject: [PATCH 13/13] Wildcard --- Snippets/ASBS/ASBS_6/ASBS_6.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Snippets/ASBS/ASBS_6/ASBS_6.csproj b/Snippets/ASBS/ASBS_6/ASBS_6.csproj index 20ae1123ad8..73167a00efb 100644 --- a/Snippets/ASBS/ASBS_6/ASBS_6.csproj +++ b/Snippets/ASBS/ASBS_6/ASBS_6.csproj @@ -5,7 +5,7 @@ - +