dotnet/orleans · error · ArgumentOutOfRangeException
MaxMetadataOnlyConflictRetries must be non-negative.
Error message
MaxMetadataOnlyConflictRetries must be non-negative.
What it means
AzureTableJournalStorageOptions.MaxMetadataOnlyConflictRetries was set to a negative value. The constructor (AzureTableJournalStorage.cs:1278) requires it non-negative because it counts retry attempts after a metadata-only ETag conflict (zero means no in-place retry, falling back immediately to InconsistentStateException). The argument blamed is `options`.
Source
Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs:1280
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)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureTableJournalStorageOptions.MetadataOnlyConflictMaxBackoff)} must be non-negative.");
}
JournalFormatKey = journalFormatKey;
TableClientProvider = tableClientProvider;
Instruments = instruments;
}
public ILogger<AzureTableJournalStorage> Logger { get; }View on GitHub (pinned to fca799fa70)
Solutions
- Set MaxMetadataOnlyConflictRetries to a non-negative integer (default 5).
- Use 0 to disable in-place metadata-conflict retries if immediate fallback is desired.
- Validate via IValidateOptions<T> at startup.
Example fix
// before options.MaxMetadataOnlyConflictRetries = -1; // after options.MaxMetadataOnlyConflictRetries = AzureTableJournalStorageOptions.DEFAULT_MAX_METADATA_ONLY_CONFLICT_RETRIES;
Defensive patterns
Strategy: validation
Validate before calling
if (options.MaxMetadataOnlyConflictRetries < 0)
throw new ArgumentOutOfRangeException(nameof(options.MaxMetadataOnlyConflictRetries), "Must be non-negative"); Type guard
static bool IsValidMaxRetries(int v) => v >= 0;
Prevention
- Use 0 to disable in-place retries instead of negative values.
- Validate via IValidateOptions<T>.
- Avoid sentinel magic numbers like -1.
When it happens
Trigger: Configuring MaxMetadataOnlyConflictRetries < 0; thrown at AzureTableJournalStorage.cs:1280.
Common situations: A config sentinel like -1 meant to mean 'unlimited' but the option does not support that; misbound integer from appsettings; arithmetic that underflowed.
Related errors
- CompactionRowCountThreshold must be positive.
- CompactionSizeThreshold must be positive.
- 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/f4732338cac87b7e.
Report an issue: GitHub.