dotnet/orleans · error · ArgumentOutOfRangeException
CompactionRowCountThreshold must be positive.
Error message
CompactionRowCountThreshold must be positive.
What it means
AzureTableJournalStorageOptions.CompactionRowCountThreshold was set to zero or a negative value. The AzureTableJournalStorageShared constructor (AzureTableJournalStorage.cs:1268) requires it to be positive because it gates IsCompactionRequested; a non-positive threshold would never trigger compaction. The argument blamed is `options`.
Source
Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs:1270
{
public AzureTableJournalStorageShared(
ILogger<AzureTableJournalStorage> logger,
IOptions<AzureTableJournalStorageOptions> options,
TableClientProvider tableClientProvider,
AzureTableJournalStorageInstruments instruments,
string? journalFormatKey = null)
{
ArgumentNullException.ThrowIfNull(logger);
ArgumentNullException.ThrowIfNull(options);
ArgumentNullException.ThrowIfNull(tableClientProvider);
Logger = logger;
Options = options.Value;
ArgumentNullException.ThrowIfNull(Options);
AzureTableJournalStorageOptions.ValidateTableName(Options.TableName);
if (Options.CompactionRowCountThreshold <= 0)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureTableJournalStorageOptions.CompactionRowCountThreshold)} must be positive.");
}
if (Options.CompactionSizeThreshold <= 0)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureTableJournalStorageOptions.CompactionSizeThreshold)} must be positive.");
}
if (Options.MaxMetadataOnlyConflictRetries < 0)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureTableJournalStorageOptions.MaxMetadataOnlyConflictRetries)} must be non-negative.");
}
if (Options.MetadataOnlyConflictInitialBackoff < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureTableJournalStorageOptions.MetadataOnlyConflictInitialBackoff)} must be non-negative.");
}
if (Options.MetadataOnlyConflictMaxBackoff < TimeSpan.Zero)View on GitHub (pinned to fca799fa70)
Solutions
- Set CompactionRowCountThreshold to a positive value (default is 10,000).
- To effectively disable size-based compaction, set a very large threshold rather than 0.
- Validate options in a startup IValidateOptions<T> so misconfiguration fails fast with a clear message.
Example fix
// before options.CompactionRowCountThreshold = 0; // after options.CompactionRowCountThreshold = AzureTableJournalStorageOptions.DEFAULT_COMPACTION_ROW_COUNT_THRESHOLD;
Defensive patterns
Strategy: validation
Validate before calling
if (options.CompactionRowCountThreshold <= 0)
throw new ArgumentOutOfRangeException(nameof(options.CompactionRowCountThreshold), "Must be positive"); Type guard
static bool IsValidCompactionRowCountThreshold(long v) => v > 0;
Prevention
- Bind options through IValidateOptions<T> for early failure.
- Never use 0 to 'disable' compaction; use a large threshold.
- Provide explicit config values rather than relying on missing bindings.
When it happens
Trigger: Configuring AzureTableJournalStorageOptions with CompactionRowCountThreshold <= 0; thrown during construction of AzureTableJournalStorageShared at line 1270.
Common situations: appsettings bound a missing/zero value; a deliberate attempt to disable compaction by setting 0 (use a very large threshold instead); typo in configuration key.
Related errors
- CompactionSizeThreshold must be positive.
- MaxMetadataOnlyConflictRetries must be non-negative.
- MetadataOnlyConflictInitialBackoff must be non-negative.
- MetadataOnlyConflictMaxBackoff must be non-negative.
- WEBSITE_PRIVATE_PORTS must contain at least one TCP port.
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/1bd20d32d44de576.
Report an issue: GitHub.