{"record":{"id":"b03db890b321e5f4","repo":"dotnet/orleans","slug":"metadataonlyconflictinitialbackoff-must-be-non-neg","errorCode":null,"errorMessage":"MetadataOnlyConflictInitialBackoff must be non-negative.","messagePattern":"MetadataOnlyConflictInitialBackoff must be non-negative\\.","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Azure/Orleans.Journaling.AzureStorage/AzureBlobJournalStorage.cs","lineNumber":1142,"sourceCode":"            AzureBlobJournalStorageInstruments instruments,\n            string? mimeType = null,\n            string? journalFormatKey = null)\n        {\n            ArgumentNullException.ThrowIfNull(logger);\n            ArgumentNullException.ThrowIfNull(options);\n            ArgumentNullException.ThrowIfNull(blobClientProvider);\n\n            Logger = logger;\n            Options = options.Value;\n            ArgumentNullException.ThrowIfNull(Options);\n            if (Options.MaxMetadataOnlyConflictRetries < 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(options), $\"{nameof(AzureBlobJournalStorageOptions.MaxMetadataOnlyConflictRetries)} must be non-negative.\");\n            }\n\n            if (Options.MetadataOnlyConflictInitialBackoff < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(options), $\"{nameof(AzureBlobJournalStorageOptions.MetadataOnlyConflictInitialBackoff)} must be non-negative.\");\n            }\n\n            if (Options.MetadataOnlyConflictMaxBackoff < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(options), $\"{nameof(AzureBlobJournalStorageOptions.MetadataOnlyConflictMaxBackoff)} must be non-negative.\");\n            }\n\n            MimeType = mimeType;\n            JournalFormatKey = journalFormatKey;\n            BlobClientProvider = blobClientProvider;\n            Instruments = instruments;\n        }\n\n        public ILogger<AzureBlobJournalStorage> Logger { get; }\n\n        public AzureBlobJournalStorageOptions Options { get; }\n\n        public string? MimeType { get; }","sourceCodeStart":1124,"sourceCodeEnd":1160,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Journaling.AzureStorage/AzureBlobJournalStorage.cs#L1124-L1160","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\noptions.MetadataOnlyConflictInitialBackoff = TimeSpan.FromMilliseconds(-5);\n\n// after\noptions.MetadataOnlyConflictInitialBackoff = TimeSpan.Zero; // retry immediately","handlingStrategy":"validation","validationCode":"if (options.MetadataOnlyConflictInitialBackoff < TimeSpan.Zero)\n    throw new ArgumentOutOfRangeException(nameof(options.MetadataOnlyConflictInitialBackoff));\n// recommended: register IValidateOptions<AzureBlobJournalStorageOptions>\nservices.AddOptions<AzureBlobJournalStorageOptions>()\n    .Validate(o => o.MetadataOnlyConflictInitialBackoff >= TimeSpan.Zero, \"InitialBackoff must be non-negative\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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)."],"tags":["azure-blob-storage","configuration","validation","argument"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}