dotnet/orleans · error · ArgumentOutOfRangeException
MetadataOnlyConflictMaxBackoff must be non-negative.
Error message
MetadataOnlyConflictMaxBackoff must be non-negative.
What it means
AzureTableJournalStorageOptions.MetadataOnlyConflictMaxBackoff was set to a negative TimeSpan. The constructor (AzureTableJournalStorage.cs:1288) requires it non-negative (TimeSpan.Zero is allowed). This caps the exponential backoff used between metadata-only conflict retries. The argument blamed is `options`.
Source
Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs:1290
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)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureTableJournalStorageOptions.MetadataOnlyConflictMaxBackoff)} must be non-negative.");
}
JournalFormatKey = journalFormatKey;
TableClientProvider = tableClientProvider;
Instruments = instruments;
}
public ILogger<AzureTableJournalStorage> Logger { get; }
public AzureTableJournalStorageOptions Options { get; }
public string? JournalFormatKey { get; }
public TableClientProvider TableClientProvider { get; }
public AzureTableJournalStorageInstruments Instruments { get; }
}
View on GitHub (pinned to fca799fa70)
Solutions
- Set MetadataOnlyConflictMaxBackoff to TimeSpan.Zero or a positive value (default 200 ms).
- Ensure the value is >= MetadataOnlyConflictInitialBackoff in practice to get a sensible schedule.
- Validate via IValidateOptions<T> at startup.
Example fix
// before options.MetadataOnlyConflictMaxBackoff = TimeSpan.FromMilliseconds(-1); // after options.MetadataOnlyConflictMaxBackoff = AzureTableJournalStorageOptions.DEFAULT_METADATA_ONLY_CONFLICT_MAX_BACKOFF;
Defensive patterns
Strategy: validation
Validate before calling
if (options.MetadataOnlyConflictMaxBackoff < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(options.MetadataOnlyConflictMaxBackoff), "Must be non-negative"); Type guard
static bool IsValidMaxBackoff(TimeSpan v) => v >= TimeSpan.Zero;
Prevention
- Keep max backoff >= initial backoff for a sensible schedule.
- Use TimeSpan.Zero only if immediate retry is intended.
- Validate via IValidateOptions<T>.
When it happens
Trigger: Configuring MetadataOnlyConflictMaxBackoff < TimeSpan.Zero; thrown at AzureTableJournalStorage.cs:1290.
Common situations: Negative TimeSpan from config binding; arithmetic that produced a negative cap; mistaking the cap for a duration to subtract.
Related errors
- CompactionRowCountThreshold must be positive.
- CompactionSizeThreshold must be positive.
- MaxMetadataOnlyConflictRetries must be non-negative.
- MetadataOnlyConflictInitialBackoff 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/adcb05a47db1bb8b.
Report an issue: GitHub.