dotnet/orleans · error · ArgumentNullException
checkpointerFactory
Error message
checkpointerFactory
What it means
EventHubAdapterReceiver requires a non-null checkpointerFactory delegate because it is called during Initialize to create an IStreamQueueCheckpointer<string> that loads and persists the Event Hub offset for the partition. Without checkpointing the receiver would re-read from the start of the partition on every restart, causing duplicate processing. The factory is invoked as checkpointerFactory(settings.Partition, cancellationToken) to produce the checkpointer.
Source
Thrown at src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs:103
monitor,
loadSheddingOptions,
environmentStatisticsProvider,
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;
}
View on GitHub (pinned to fca799fa70)
Solutions
- Ensure a stream checkpointer is configured, e.g., by calling the appropriate checkpointer configuration extension on the Event Hub stream provider.
- If constructing manually, pass a Func<string, CancellationToken, Task<IStreamQueueCheckpointer<string>>> that returns a valid checkpointer (e.g., a mock in tests).
- Verify StreamCheckpointerConfigurationValidator passes during silo startup — it checks for IStreamQueueCheckpointerFactory keyed services.
Example fix
// before
var receiver = new EventHubAdapterReceiver(
settings, cacheFactory, null /* checkpointerFactory */, ...);
// after
Func<string, CancellationToken, Task<IStreamQueueCheckpointer<string>>> checkpointerFactory =
async (partition, ct) =>
{
var checkpointer = new MockCheckpointer();
await checkpointer.Load(ct);
return checkpointer;
};
var receiver = new EventHubAdapterReceiver(
settings, cacheFactory, checkpointerFactory, ...); Defensive patterns
Strategy: validation
Validate before calling
// Verify checkpointer factory is non-null:
if (checkpointerFactory is null)
throw new InvalidOperationException(
"A checkpointer factory is required. Ensure IStreamQueueCheckpointerFactory " +
"is registered in DI for this stream provider."); Prevention
- Configure a stream checkpointer (e.g., Azure Blob Storage based) when setting up Event Hub streams.
- Verify StreamCheckpointerConfigurationValidator passes during silo startup.
- In tests, pass a Func<string, CancellationToken, Task<IStreamQueueCheckpointer<string>>> that returns a mock checkpointer.
When it happens
Trigger: Constructing EventHubAdapterReceiver with checkpointerFactory set to null. In the factory path, the checkpointer factory is passed from EventHubAdapterFactory.MakeReceiver as (partition, ct) => this.checkpointerFactory.Create(partition, ct), where checkpointerFactory is resolved from keyed DI services. Fires on direct construction or when the IStreamQueueCheckpointerFactory is not registered in DI.
Common situations: Forgetting to register a checkpointer provider (e.g., Azure Blob Storage checkpointer) in the Event Hub stream configuration; manual construction in tests without a checkpointer; the IStreamQueueCheckpointerFactory keyed service is missing from DI, though in that case StreamCheckpointerConfigurationValidator would typically catch it first.
Related errors
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/023b262d0190b175.
Report an issue: GitHub.