dotnet/orleans · error · ArgumentOutOfRangeException
MetadataOnlyConflictInitialBackoff must be non-negative.
Error message
MetadataOnlyConflictInitialBackoff must be non-negative.
What it means
Thrown during AzureBlobJournalStorageShared construction when AzureBlobJournalStorageOptions.MetadataOnlyConflictInitialBackoff is negative. This TimeSpan is the seed delay for the exponential backoff applied between metadata-only conflict retries. A negative duration is invalid and is rejected at construction time. TimeSpan.Zero is allowed and disables backoff.
Source
Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureBlobJournalStorage.cs:1142
AzureBlobJournalStorageInstruments instruments,
string? mimeType = null,
string? journalFormatKey = null)
{
ArgumentNullException.ThrowIfNull(logger);
ArgumentNullException.ThrowIfNull(options);
ArgumentNullException.ThrowIfNull(blobClientProvider);
Logger = logger;
Options = options.Value;
ArgumentNullException.ThrowIfNull(Options);
if (Options.MaxMetadataOnlyConflictRetries < 0)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureBlobJournalStorageOptions.MaxMetadataOnlyConflictRetries)} must be non-negative.");
}
if (Options.MetadataOnlyConflictInitialBackoff < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureBlobJournalStorageOptions.MetadataOnlyConflictInitialBackoff)} must be non-negative.");
}
if (Options.MetadataOnlyConflictMaxBackoff < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(options), $"{nameof(AzureBlobJournalStorageOptions.MetadataOnlyConflictMaxBackoff)} must be non-negative.");
}
MimeType = mimeType;
JournalFormatKey = journalFormatKey;
BlobClientProvider = blobClientProvider;
Instruments = instruments;
}
public ILogger<AzureBlobJournalStorage> Logger { get; }
public AzureBlobJournalStorageOptions Options { get; }
public string? MimeType { get; }View on GitHub (pinned to fca799fa70)
Solutions
- Set MetadataOnlyConflictInitialBackoff to TimeSpan.Zero or a positive value such as the default 10 ms.
- Add an IValidateOptions<AzureBlobJournalStorageOptions> to catch negative TimeSpans at startup.
- If backoff is unwanted, use TimeSpan.Zero rather than a negative value.
Example fix
// before options.MetadataOnlyConflictInitialBackoff = TimeSpan.FromMilliseconds(-5); // after options.MetadataOnlyConflictInitialBackoff = TimeSpan.Zero; // retry immediately
Defensive patterns
Strategy: validation
Validate before calling
if (options.MetadataOnlyConflictInitialBackoff < TimeSpan.Zero)
throw new ArgumentOutOfRangeException(nameof(options.MetadataOnlyConflictInitialBackoff));
// recommended: register IValidateOptions<AzureBlobJournalStorageOptions>
services.AddOptions<AzureBlobJournalStorageOptions>()
.Validate(o => o.MetadataOnlyConflictInitialBackoff >= TimeSpan.Zero, "InitialBackoff must be non-negative"); Prevention
- Use IValidateOptions to catch negative TimeSpans at startup.
- Prefer TimeSpan.Zero over negative values to disable backoff.
- Double-check JSON deserialization of TimeSpan fields (use '00:00:00.010' format).
When it happens
Trigger: Setting options.MetadataOnlyConflictInitialBackoff to a value less than TimeSpan.Zero and then constructing the provider or the shared storage object. Validation runs in the AzureBlobJournalStorageShared constructor.
Common situations: Loading the value from configuration where a missing key deserializes to a sentinel; arithmetic that subtracts TimeSpans yielding a negative result; confusing initial backoff with max backoff and entering a negative seed.
Related errors
- MaxMetadataOnlyConflictRetries must be non-negative.
- MetadataOnlyConflictMaxBackoff must be non-negative.
- Journal metadata property names must not contain null charac
- The journal id must not be the default value.
- Value cannot be null. (Parameter 'createClientCallback')
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/b03db890b321e5f4.
Report an issue: GitHub.