{"record":{"id":"091e688a094bfa69","repo":"microsoft/aspire","slug":"the-materialization-timeout-must-be-positive-and-at-most-int","errorCode":null,"errorMessage":"The materialization timeout must be positive and at most int.MaxValue milliseconds (~24.85 days).","messagePattern":"The materialization timeout must be positive and at most int\\.MaxValue milliseconds \\(~24\\.85 days\\)\\.","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Radius/Secrets/RadiusSecretStoreExtensions.cs","lineNumber":286,"sourceCode":"    /// <param name=\"timeout\">A positive materialization timeout, at most <see cref=\"int.MaxValue\"/> milliseconds (~24.85 days).</param>\n    /// <returns>The same store builder for chaining.</returns>\n    /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"timeout\"/> is not positive or exceeds the supported timer range.</exception>\n    [Experimental(\"ASPIRERADIUS006\", UrlFormat = \"https://aka.ms/aspire/diagnostics/{0}\")]\n    [AspireExportIgnore(Reason = \"Sealed-secret deploy-timing knob with no polyglot ATS equivalent.\")]\n    public static IResourceBuilder<RadiusSecretStoreResource> WithMaterializationTimeout(\n        this IResourceBuilder<RadiusSecretStoreResource> store,\n        TimeSpan timeout)\n    {\n        ArgumentNullException.ThrowIfNull(store);\n\n        // The deploy path bounds materialization with CancellationTokenSource.CancelAfter, which\n        // accepts at most int.MaxValue milliseconds (~24.85 days), and also adds this budget to\n        // DateTimeOffset.UtcNow. A larger value (e.g. TimeSpan.MaxValue) would pass a \"positive\"\n        // check yet throw ArgumentOutOfRangeException mid-deploy, so reject it here at configuration\n        // time. See https://learn.microsoft.com/dotnet/api/system.threading.cancellationtokensource.cancelafter.\n        if (timeout <= TimeSpan.Zero || timeout.TotalMilliseconds > int.MaxValue)\n        {\n            throw new ArgumentOutOfRangeException(\n                nameof(timeout),\n                timeout,\n                \"The materialization timeout must be positive and at most int.MaxValue milliseconds (~24.85 days).\");\n        }\n\n        store.Resource.MaterializationTimeout = timeout;\n        store.Resource.MaterializationTimeoutWasSet = true;\n        return store;\n    }\n\n    // Validates every key without mutating the store's population, so a later invalid key cannot\n    // leave the population partially assigned (which would then trip the ASPIRERADIUS065 guard on a\n    // corrected retry). Returns the validated keys for the caller to commit atomically.\n    private static List<string> ValidateKeys(string[] keys)\n    {\n        ArgumentNullException.ThrowIfNull(keys);\n        foreach (var key in keys)\n        {","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Radius/Secrets/RadiusSecretStoreExtensions.cs#L268-L304","documentation":"WithMaterializationTimeout stores a timeout later passed to CancellationTokenSource.CancelAfter, which accepts at most int.MaxValue milliseconds (~24.85 days) and adds it to DateTimeOffset.UtcNow. A value like TimeSpan.MaxValue would pass a naive positivity check yet throw ArgumentOutOfRangeException mid-deploy, so it is rejected up front.","triggerScenarios":"Calling WithMaterializationTimeout with TimeSpan.Zero, a negative TimeSpan, or a TimeSpan whose TotalMilliseconds exceeds int.MaxValue (e.g. TimeSpan.MaxValue, TimeSpan.FromDays(30)).","commonSituations":"Trying to express 'no timeout' with TimeSpan.MaxValue or TimeSpan.FromMilliseconds(-1); copying a timeout constant defined for Task.Delay-style long waits.","solutions":["Pass a positive TimeSpan within int.MaxValue milliseconds (under ~24.85 days)","To disable the limit, don't call WithMaterializationTimeout instead of passing an enormous value","Clamp or validate user-supplied durations before calling"],"exampleFix":"// before\n.WithMaterializationTimeout(TimeSpan.MaxValue)\n// after\n.WithMaterializationTimeout(TimeSpan.FromHours(1))","handlingStrategy":"validation","validationCode":"if (timeout <= TimeSpan.Zero || timeout.TotalMilliseconds > int.MaxValue) throw new ArgumentOutOfRangeException(nameof(timeout));","typeGuard":null,"tryCatchPattern":"try { store.WithMaterializationTimeout(timeout); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == nameof(timeout)) { logger.LogError(ex, \"Materialization timeout out of range\"); throw; }","preventionTips":["Clamp durations to TimeSpan.FromMilliseconds(int.MaxValue)","Never use TimeSpan.MaxValue as a 'no timeout' sentinel — omit the call instead","Add config-layer validation for user-supplied durations"],"tags":["radius","secrets","timeout","validation"],"backgroundTag":"argument-out-of-range","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}