dotnet/aspnetcore · error · ArgumentException

ExpiredItemsDeletionInterval cannot be less than the…

Error message

ExpiredItemsDeletionInterval cannot be less than the minimum value of {0} minutes.

What it means

Thrown in the SqlServerCache constructor when ExpiredItemsDeletionInterval is set but is below the minimum allowed interval (MinimumExpiredItemsDeletionInterval). The interval controls how often a background sweep deletes expired rows; too small a value would cause excessive database load.

Solutions

  1. Set ExpiredItemsDeletionInterval to a TimeSpan >= MinimumExpiredItemsDeletionInterval (the value named in the message).
  2. If you don't need a custom interval, omit the option to use the default (DefaultExpiredItemsDeletionInterval).
  3. Double-check that the value is a TimeSpan and units are correct (minutes, not seconds).

Example fix

// before: too small
services.AddDistributedSqlServerCache(o => { o.ExpiredItemsDeletionInterval = TimeSpan.FromSeconds(10); ... });

// after: at or above the minimum (default is 30 minutes)
services.AddDistributedSqlServerCache(o => { o.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(30); ... });
Defensive patterns

Strategy: validation

Validate before calling

if (options.ExpiredItemsDeletionInterval.HasValue && options.ExpiredItemsDeletionInterval.Value < SqlServerCache.MinimumExpiredItemsDeletionInterval) { /* raise or omit option */ }

Prevention

When it happens

Trigger: Constructing/configuring SqlServerCache with options.ExpiredItemsDeletionInterval having a value but less than MinimumExpiredItemsDeletionInterval (the message reports the threshold in minutes).

Common situations: Setting the interval to a few seconds intending 'aggressive cleanup'; misreading the option as milliseconds instead of a TimeSpan; copying a config value from another cache provider with different semantics.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/135d7292c4c2a03d. Report an issue: GitHub.

Appendix: source

Thrown at src/Caching/SqlServer/src/SqlServerCache.cs:47

    private readonly TimeSpan _defaultSlidingExpiration;
    private readonly Object _mutex = new Object();

    /// <summary>
    /// Initializes a new instance of <see cref="SqlServerCache"/>.
    /// </summary>
    /// <param name="options">The configuration options.</param>
    public SqlServerCache(IOptions<SqlServerCacheOptions> options)
    {
        var cacheOptions = options.Value;

        ArgumentThrowHelper.ThrowIfNullOrEmpty(cacheOptions.ConnectionString);
        ArgumentThrowHelper.ThrowIfNullOrEmpty(cacheOptions.SchemaName);
        ArgumentThrowHelper.ThrowIfNullOrEmpty(cacheOptions.TableName);

        if (cacheOptions.ExpiredItemsDeletionInterval.HasValue &&
            cacheOptions.ExpiredItemsDeletionInterval.Value < MinimumExpiredItemsDeletionInterval)
        {
            throw new ArgumentException(
                $"{nameof(SqlServerCacheOptions.ExpiredItemsDeletionInterval)} cannot be less than the minimum " +
                $"value of {MinimumExpiredItemsDeletionInterval.TotalMinutes} minutes.");
        }
        if (cacheOptions.DefaultSlidingExpiration <= TimeSpan.Zero)
        {
#pragma warning disable CA2208 // Instantiate argument exceptions correctly
            throw new ArgumentOutOfRangeException(
                nameof(cacheOptions.DefaultSlidingExpiration),
                cacheOptions.DefaultSlidingExpiration,
                "The sliding expiration value must be positive.");
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
        }

        _systemClock = cacheOptions.SystemClock ?? new SystemClock();
        _expiredItemsDeletionInterval =
            cacheOptions.ExpiredItemsDeletionInterval ?? DefaultExpiredItemsDeletionInterval;
        _deleteExpiredCachedItemsDelegate = DeleteExpiredCacheItems;
        _defaultSlidingExpiration = cacheOptions.DefaultSlidingExpiration;

View on GitHub (pinned to 3600ca084e)