dotnet/aspnetcore · error · ArgumentException
ExpiredItemsDeletionInterval cannot be less than the minimum
Error message
ExpiredItemsDeletionInterval cannot be less than the minimum value of {0} minutes. What it means
Thrown by the SqlServerCache constructor (line 47) when SqlServerCacheOptions.ExpiredItemsDeletionInterval is set to a value less than the MinimumExpiredItemsDeletionInterval (5 minutes, line 21). The background expired-item scan runs at this interval; setting it too low would cause excessive database churn. The exception type is ArgumentException, thrown at construction time (typically during DI service registration), causing application startup failure.
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 294cab2f9b)
Solutions
- Set ExpiredItemsDeletionInterval to at least 5 minutes, or leave it unset to use the default (30 minutes).
- If faster cleanup is needed, leave it at the minimum and call DeleteExpiredCacheItems via a custom scheduled job.
- Verify the configuration value is specified as a correct TimeSpan (e.g., "00:30:00" for 30 minutes in config).
Example fix
// before — below the 5-minute floor
services.AddDistributedSqlServerCache(o =>
{
o.ExpiredItemsDeletionInterval = TimeSpan.FromSeconds(30);
});
// after — at or above the 5-minute minimum (or omit for default 30 min)
services.AddDistributedSqlServerCache(o =>
{
o.ExpiredItemsDeletionInterval = TimeSpan.FromMinutes(5);
}); Defensive patterns
Strategy: validation
Validate before calling
// Validate before constructing
var minInterval = TimeSpan.FromMinutes(5);
if (cacheOptions.ExpiredItemsDeletionInterval.HasValue
&& cacheOptions.ExpiredItemsDeletionInterval.Value < minInterval)
{
throw new ArgumentException($"ExpiredItemsDeletionInterval must be >= {minInterval.TotalMinutes} minutes.");
} Prevention
- Leave ExpiredItemsDeletionInterval unset to use the safe 30-minute default.
- If customizing, verify the value is >= 5 minutes.
When it happens
Trigger: SqlServerCache is instantiated (via AddDistributedSqlServerCache or new SqlServerCache) with options.ExpiredItemsDeletionInterval set to a TimeSpan less than 5 minutes.
Common situations: Over-aggressive cleanup configuration; a misunderstanding that the value is in minutes vs seconds; copying a value from another cache provider without adjusting units; a config typo like TimeSpan.FromSeconds(30).
Related errors
- The sliding expiration value must be positive.
- The absolute expiration value must be in the future.
- Either absolute or sliding expiration needs to be provided.
- The absolute expiration value must be in the future.
- Circuit options have already been configured.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/135d7292c4c2a03d.
Report an issue: GitHub.