dotnet/orleans · error · ArgumentNullException
cacheFactory
Error message
cacheFactory
What it means
EventHubAdapterReceiver requires a non-null cacheFactory delegate because it is called during Initialize to create the IEventHubQueueCache for each partition — the cache holds incoming EventData as CachedMessage objects and serves them to stream consumers via cursors. Without it the receiver cannot buffer any messages and the Initialize method would fail with a NullReferenceException at the cacheFactory invocation.
Source
Thrown at src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs:102
loggerFactory,
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 EventHubAdapterFactory.Init() is called before any receiver is created, as Init sets CacheFactory via CreateCacheFactory.
- If constructing EventHubAdapterReceiver directly, pass a valid Func<string, IStreamQueueCheckpointer<string>, ILoggerFactory, IEventHubQueueCache> that creates an EventHubQueueCache.
- If overriding CreateCacheFactory in a subclass, ensure it returns a non-null IEventHubQueueCacheFactory.
Example fix
// before
var receiver = new EventHubAdapterReceiver(
settings, null /* cacheFactory */, checkpointerFactory, ...);
// after
Func<string, IStreamQueueCheckpointer<string>, ILoggerFactory, IEventHubQueueCache> cacheFactory =
(partition, checkpointer, loggerFactory) =>
new EventHubQueueCache(partition, 1000, bufferPool, dataAdapter, evictionStrategy, checkpointer, logger, cacheMonitor, null, null);
var receiver = new EventHubAdapterReceiver(
settings, cacheFactory, checkpointerFactory, ...); Defensive patterns
Strategy: validation
Validate before calling
// Ensure CacheFactory is set before creating receivers:
if (factory.CacheFactory is null)
throw new InvalidOperationException(
"CacheFactory is not set. Call EventHubAdapterFactory.Init() first."); Prevention
- Always call Init() on EventHubAdapterFactory before creating receivers, as it sets CacheFactory.
- If overriding CreateCacheFactory, ensure it returns a non-null IEventHubQueueCacheFactory.
- In manual/test construction, provide a Func that creates a real EventHubQueueCache.
When it happens
Trigger: Constructing EventHubAdapterReceiver with cacheFactory set to null. In the factory path, CacheFactory is set from CreateCacheFactory(cacheOptions).CreateCache during EventHubAdapterFactory.Init, and passed through MakeReceiver. Fires only on direct construction or a custom factory that leaves CacheFactory unset.
Common situations: Manual construction in tests without wiring up a cache factory; a subclass of EventHubAdapterFactory that overrides Init or CreateCacheFactory incorrectly and produces a null CacheFactory; calling the EventHubAdapterReceiver constructor before EventHubAdapterFactory.Init has run (which sets CacheFactory).
Related errors
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/3b28bbc16d153a26.
Report an issue: GitHub.