Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Modernization
Samples

Retry failed messages using ServicePulse

Component: NServiceBus
NuGet Package: NServiceBus (10-pre)
This page targets a pre-release version. Pre-releases are subject to change and samples are not guaranteed to be fully functional.

This sample shows how to retry a failed message. The sample uses the Learning Transport and a portable version of the Particular Service Platform tools. Installing ServiceControl is not required.

Running the solution

Running the solution starts 3 console windows. Wait a moment until the ServicePulse window opens in the browser.

service-pulse-fresh

Sender

The sender is a program that uses NServiceBus to send simple test messages.

<div class='alert alert-primary'>NServiceBus.LicenseManager[0]</div>

      Selected active license from C:\ProgramData\ParticularSoftware\license.xml
      License Expiration: 2026-07-15
Press 'Enter' to send a new message. Press any other key to finish.
<div class='alert alert-primary'>Microsoft.Hosting.Lifetime[0]</div>

      Application started. Press Ctrl+C to shut down.
<div class='alert alert-primary'>Microsoft.Hosting.Lifetime[0]</div>

      Hosting environment: Production
<div class='alert alert-primary'>Microsoft.Hosting.Lifetime[0]</div>

      Content root path: C:\git\p\docs.particular.net\samples\servicecontrol\retry-messages\Core_9\Sender\bin\Debug\net9.0
Press 'Enter' to send a new message. Press any other key to finish.

Press Enter in the Sender console window to send one.

Receiver

The receiver reads messages off a queue and processes them. By default, it runs in a fault simulation mode, which causes message processing to fail, including the one that has just been sent.

<div class='alert alert-primary'>NServiceBus.LicenseManager[0]</div>

      Selected active license from C:\ProgramData\ParticularSoftware\license.xml
      License Expiration: 2026-07-15
Press 't' to toggle fault mode.
<div class='alert alert-primary'>Microsoft.Hosting.Lifetime[0]</div>

      Application started. Press Ctrl+C to shut down.
<div class='alert alert-primary'>Microsoft.Hosting.Lifetime[0]</div>

      Hosting environment: Production
<div class='alert alert-primary'>Microsoft.Hosting.Lifetime[0]</div>

      Content root path: C:\git\p\docs.particular.net\samples\servicecontrol\retry-messages\Core_9\Receiver\bin\Debug\net9.0
<div class='alert alert-primary'>Toggle[0]</div>

      Received message.
fail: NServiceBus.MoveToError[0]
      Moving message '6e387659-ea6b-47ee-8223-b31b00aa3d9f' to the error queue 'error' because processing failed due to an exception:
      System.Exception: Simulated error.
         at SimpleMessageHandler.Handle(SimpleMessage message, IMessageHandlerContext context) in C:\git\p\docs.particular.net\samples\servicecontrol\retry-messages\Core_9\Receiver\SimpleMessageHandler.cs:line 25
         at NServiceBus.Pipeline.MessageHandler.Invoke(Object message, IMessageHandlerContext handlerContext) in /_/src/NServiceBus.Core/Pipeline/Incoming/MessageHandler.cs:line 43
(...)

Press t to disable the fault simulation mode so that the message is processed correctly once retried.

t
Fault mode disabled

ServicePulse

Going back to the ServicePulse browser window, there is a notification on the dashboard about one failed message.

service-pulse-dash-error

Click on the failure symbol to see the datails. You can inspect the message headers as well as the payload.

service-pulse-error-details

Now click Request retry to initiate the message retry process i.e. sending the message back to the receiver's input queue for reprocessing.

service-pulse-retry-in-progress

Once the process is completed, go back to the Receiver console window.

service-pulse-retry-completed

Receiver

You can now notice that the message has been successfully processed.

t
Fault mode disabled
<div class='alert alert-primary'>Toggle[0]</div>

      Received message.
<div class='alert alert-primary'>Toggle[0]</div>

      Successfully processed message.

Code walk-through

For simplicity, both the immediate and the delayed retries are disabled in the sample. As a result, messages are moved to the error queue after a single failed processing attempt:

var recoverability = endpointConfiguration.Recoverability();

recoverability.Delayed(
    customizations: retriesSettings =>
    {
        retriesSettings.NumberOfRetries(0);
    });
recoverability.Immediate(
    customizations: retriesSettings =>
    {
        retriesSettings.NumberOfRetries(0);
    });

The receiver's failure mode is controlled by the FaultMode property. When true processing of SimpleMessage messages ends with an exception.

logger.LogInformation("Received message.");
if (FaultMode)
{
    throw new Exception("Simulated error.");
}
logger.LogInformation("Successfully processed message.");
return Task.CompletedTask;