Outbox Setup throws incorrect exception "requires transport to be running in ReceiveOnly"

On upgrading to NServiceBus v8.0.0 (prev 7.8.0) and NServiceBus.Transport.AzureServiceBus 3.1.0 (prev 2.0.3) an exception is thrown at startup with Outbox enabled (SQL persistence). The transport is configured for SendsAtomicWithReceive which has worked with the previous version and is documented as supported.

When stepping through the line “config.Settings.SetDefault(TransportTransactionMode.ReceiveOnly);” seems to have been removed from OutboxConfigExtensions causing the issue?

Has anyone else experienced this post upgarding?

System.Exception
  HResult=0x80131500
  Message=Outbox requires transport to be running in `ReceiveOnly` mode. Use the `TransportTransactionMode` property on the transport definition to specify the transaction mode.
  Source=NServiceBus.Core
  StackTrace:
   at NServiceBus.Features.Outbox.Setup(FeatureConfigurationContext context) in /_/src/NServiceBus.Core/Reliability/Outbox/Outbox.cs:line 55
   at NServiceBus.Features.Feature.SetupFeature(FeatureConfigurationContext config) in /_/src/NServiceBus.Core/Features/Feature.cs:line 206
   at NServiceBus.Features.FeatureActivator.FeatureInfo.InitializeFrom(FeatureConfigurationContext featureConfigurationContext) in /_/src/NServiceBus.Core/Features/FeatureActivator.cs:line 241
   at NServiceBus.Features.FeatureActivator.ActivateFeature(FeatureInfo featureInfo, List`1 featuresToActivate, FeatureConfigurationContext featureConfigurationContext) in /_/src/NServiceBus.Core/Features/FeatureActivator.cs:line 206
   at NServiceBus.Features.FeatureActivator.SetupFeatures(FeatureConfigurationContext featureConfigurationContext) in /_/src/NServiceBus.Core/Features/FeatureActivator.cs:line 57
   at NServiceBus.FeatureComponent.Initalize(FeatureConfigurationContext featureConfigurationContext) in /_/src/NServiceBus.Core/Features/FeatureComponent.cs:line 29
   at NServiceBus.EndpointCreator.Configure() in /_/src/NServiceBus.Core/EndpointCreator.cs:line 63
   at NServiceBus.EndpointCreator.Create(SettingsHolder settings, Configuration hostingConfiguration) in /_/src/NServiceBus.Core/EndpointCreator.cs:line 28
   at NServiceBus.HostCreator.CreateWithExternallyManagedContainer(EndpointConfiguration endpointConfiguration, IServiceCollection serviceCollection) in /_/src/NServiceBus.Core/Hosting/HostCreator.cs:line 30
   at NServiceBus.EndpointWithExternallyManagedContainer.Create(EndpointConfiguration configuration, IServiceCollection serviceCollection) in /_/src/NServiceBus.Core/EndpointWithExternallyManagedContainer.cs:line 18
   at NServiceBus.HostBuilderExtensions.<>c__DisplayClass0_0.<UseNServiceBus>b__0(HostBuilderContext ctx, IServiceCollection serviceCollection) in /_/src/NServiceBus.Extensions.Hosting/HostBuilderExtensions.cs:line 34
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider() in /_/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs:line 286
   at Microsoft.Extensions.Hosting.HostBuilder.Build() in /_/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs:line 149
   at Program.<<Main>$>d__0.MoveNext() in C:\Users\NickSimpson\source\repos\TSF\Insight\Service\src\Directory\Directory.Infrastructure.Command.Service\Program.cs:line 153
   at Program.<Main>(String[] args)

NServiceBus 8.0.0
NServiceBus.Transport.AzureServiceBus 3.1.0
NServiceBus.Persistence.Sql.TransactionalSession 7.0.0

This is by design. See upgrade guide.

NServiceBus version 8 requires the transport transaction mode to be set explicitly to ReceiveOnly when using the outbox feature

2 Likes

Thanks for the quick response and help. Setting ReceiveOnly explicitly resolved the issue. As it worked pre v8.0.0 I was wondering why it no longer worked? The comment in Outbox.cs cover this. Thanks.

// ForceBatchDispatchToBeIsolatedBehavior set the dispatch consistency to isolated which instructs
// the transport to not enlist the outgoing operation in the incoming message transaction. Unfortunately
// this is not enough. We cannot allow the transport to operate in SendsWithAtomicReceive because a transport
// might then only release the outgoing operations when the incoming transport transaction is committed meaning
// the actual sends would happen after we have set the outbox record as dispatched and not as part of
// TransportReceiveToPhysicalMessageConnector fork into the batched dispatched phase. Should acknowledging
// the incoming operation fail and the message be retried we would already have cleared the outbox record's
// transport operations leading to outgoing message loss.
1 Like

FYI I’ve noticed that the outbox configuration documentation hasn’t been updated correctly to reflect the v8 state as described in the upgrade guide so there’s a PR to fix that too.