dotnet/orleans · error · ArgumentNullException

cacheOptions

Error message

cacheOptions

What it means

EventHubAdapterFactory rejects a null EventHubStreamCachePressureOptions in its constructor because cache-pressure monitoring needs concrete thresholds to apply back-pressure and avoid unbounded cache growth. This options object carries the slow-consuming flow-control threshold, pressure window size, and averaging monitor threshold. Without it the adapter cannot determine when to stop reading from Event Hub partitions.

Source

Thrown at src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterFactory.cs:123

        internal HashRingBasedPartitionedStreamQueueMapper EventHubQueueMapper => streamQueueMapper;

        public EventHubAdapterFactory(
            string name,
            EventHubOptions ehOptions,
            EventHubReceiverOptions receiverOptions,
            EventHubStreamCachePressureOptions cacheOptions, 
            StreamCacheEvictionOptions cacheEvictionOptions,
            StreamStatisticOptions statisticOptions,
            IEventHubDataAdapter dataAdapter,
            IServiceProvider serviceProvider,
            ILoggerFactory loggerFactory,
            IEnvironmentStatisticsProvider environmentStatisticsProvider)
        {
            this.Name = name;
            this.cacheEvictionOptions = cacheEvictionOptions ?? throw new ArgumentNullException(nameof(cacheEvictionOptions));
            this.statisticOptions = statisticOptions ?? throw new ArgumentNullException(nameof(statisticOptions));
            this.ehOptions = ehOptions ?? throw new ArgumentNullException(nameof(ehOptions));
            this.cacheOptions = cacheOptions?? throw new ArgumentNullException(nameof(cacheOptions));
            this.dataAdapter = dataAdapter ?? throw new ArgumentNullException(nameof(dataAdapter));
            this.receiverOptions = receiverOptions?? throw new ArgumentNullException(nameof(receiverOptions));
            this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
            this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
            this.environmentStatisticsProvider = environmentStatisticsProvider;
            this.orleansInstruments = serviceProvider.GetRequiredService<OrleansInstruments>();
        }

        public virtual void Init()
        {
            this.receivers = new ConcurrentDictionary<QueueId, EventHubAdapterReceiver>();

            InitEventHubClient();

            if (this.CacheFactory == null)
            {
                this.CacheFactory = CreateCacheFactory(this.cacheOptions).CreateCache;
            }

View on GitHub (pinned to fca799fa70)

Solutions

  1. If constructing the factory manually, pass a new EventHubStreamCachePressureOptions() (defaults are valid) instead of null.
  2. If using the standard DI path, ensure AddEventHubStreams is called on the silo/client builder so that named EventHubStreamCachePressureOptions are registered.
  3. If subclassing EventHubAdapterFactory, do not bypass the base constructor's null-check — pass all required options through.

Example fix

// before
var factory = new EventHubAdapterFactory(
    name, ehOptions, receiverOptions, null /* cacheOptions */, ...);

// after
var factory = new EventHubAdapterFactory(
    name, ehOptions, receiverOptions, new EventHubStreamCachePressureOptions(), ...);
Defensive patterns

Strategy: validation

Validate before calling

// Before constructing EventHubAdapterFactory manually:
if (cacheOptions is null)
    throw new InvalidOperationException(
        "EventHubStreamCachePressureOptions must be configured. " +
        "Call .Configure<EventHubStreamCachePressureOptions>(...) or use AddEventHubStreams.");

Prevention

When it happens

Trigger: Constructing EventHubAdapterFactory directly with cacheOptions set to null, or a custom IQueueAdapterFactory/DI registration that supplies null for the EventHubStreamCachePressureOptions parameter. In the default EventHubAdapterFactory.Create path this is resolved via services.GetOptionByName<EventHubStreamCachePressureOptions>(name) which returns a non-null default, so this fires only on manual construction or a broken custom factory.

Common situations: Writing unit tests or a custom EventHubAdapterFactory subclass and passing null for cacheOptions; a DI container misconfiguration where a keyed/named options object is overridden with null; upgrading Orleans versions where the constructor signature changed and an outdated manual call site passes the wrong argument.

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/f524511dd0b9d346. Report an issue: GitHub.