dotnet/orleans · error · ArgumentNullException
monitor
Error message
monitor
What it means
EventHubAdapterReceiver requires a non-null IQueueAdapterReceiverMonitor because it reports initialization success/failure, read latency, message counts, and shutdown metrics for each Event Hub partition. The monitor is called with TrackInitialization, TrackRead, TrackMessagesReceived, and TrackShutdown throughout the receiver lifecycle. Without it the runtime cannot detect slow or failing partitions.
Source
Thrown at src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs:106
eventHubReceiverFactory)
{
}
public EventHubAdapterReceiver(EventHubPartitionSettings settings,
Func<string, IStreamQueueCheckpointer<string>, ILoggerFactory, IEventHubQueueCache> cacheFactory,
Func<string, CancellationToken, Task<IStreamQueueCheckpointer<string>>> checkpointerFactory,
ILoggerFactory loggerFactory,
IQueueAdapterReceiverMonitor monitor,
LoadSheddingOptions loadSheddingOptions,
IEnvironmentStatisticsProvider environmentStatisticsProvider,
Func<EventHubPartitionSettings, string, ILogger, IEventHubReceiver>? eventHubReceiverFactory = null)
{
this.settings = settings ?? throw new ArgumentNullException(nameof(settings));
this.cacheFactory = cacheFactory ?? throw new ArgumentNullException(nameof(cacheFactory));
this.checkpointerFactory = checkpointerFactory ?? throw new ArgumentNullException(nameof(checkpointerFactory));
this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
this.logger = this.loggerFactory.CreateLogger<EventHubAdapterReceiver>();
this.monitor = monitor ?? throw new ArgumentNullException(nameof(monitor));
this.loadSheddingOptions = loadSheddingOptions ?? throw new ArgumentNullException(nameof(loadSheddingOptions));
this.environmentStatisticsProvider = environmentStatisticsProvider;
this.eventHubReceiverFactory = eventHubReceiverFactory == null ? EventHubAdapterReceiver.CreateReceiver : eventHubReceiverFactory;
}
public async Task Initialize(TimeSpan timeout)
{
LogInfoInitializingEventHubPartition(this.settings.Hub.EventHubName, this.settings.Partition);
// if receiver was already running, do nothing
if (ReceiverRunning == Interlocked.Exchange(ref this.receiverState, ReceiverRunning))
{
return;
}
using var cancellation = new CancellationTokenSource(timeout);
await Initialize(cancellation.Token);
}View on GitHub (pinned to fca799fa70)
Solutions
- Pass a valid IQueueAdapterReceiverMonitor such as DefaultEventHubReceiverMonitor or a test implementation.
- If overriding ReceiverMonitorFactory in a subclass, ensure it never returns null.
- In tests, create a no-op or mock IQueueAdapterReceiverMonitor implementation.
Example fix
// before
var receiver = new EventHubAdapterReceiver(
settings, cacheFactory, checkpointerFactory, loggerFactory,
null /* monitor */, loadSheddingOptions, envStats);
// after
var dimensions = new EventHubReceiverMonitorDimensions { EventHubPartition = "0", EventHubPath = "myhub" };
var monitor = new DefaultEventHubReceiverMonitor(dimensions, orleansInstruments);
var receiver = new EventHubAdapterReceiver(
settings, cacheFactory, checkpointerFactory, loggerFactory,
monitor, loadSheddingOptions, envStats); Defensive patterns
Strategy: validation
Validate before calling
// Ensure monitor is non-null before constructing the receiver:
if (monitor is null)
monitor = new DefaultEventHubReceiverMonitor(dimensions, orleansInstruments); Prevention
- Use the default ReceiverMonitorFactory which creates DefaultEventHubReceiverMonitor.
- When overriding ReceiverMonitorFactory in a subclass, ensure it never returns null.
- In tests, create a simple no-op IQueueAdapterReceiverMonitor implementation.
When it happens
Trigger: Constructing EventHubAdapterReceiver with monitor set to null. In the factory path, the monitor is created by ReceiverMonitorFactory (defaulting to DefaultEventHubReceiverMonitor) during EventHubAdapterFactory.MakeReceiver and is always non-null. Fires on direct construction or if a custom ReceiverMonitorFactory returns null.
Common situations: Manual construction in tests without wiring a monitor; overriding ReceiverMonitorFactory in a subclass of EventHubAdapterFactory and having it return null; passing a test double that is unintentionally null.
Related errors
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/e3b145885c291be3.
Report an issue: GitHub.