microsoft/aspire · error · ArgumentOutOfRangeException

The materialization timeout must be positive and at most…

Error message

The materialization timeout must be positive and at most int.MaxValue milliseconds (~24.85 days).

What it means

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.

Solutions

  1. Pass a positive TimeSpan within int.MaxValue milliseconds (under ~24.85 days)
  2. To disable the limit, don't call WithMaterializationTimeout instead of passing an enormous value
  3. Clamp or validate user-supplied durations before calling

Example fix

// before
.WithMaterializationTimeout(TimeSpan.MaxValue)
// after
.WithMaterializationTimeout(TimeSpan.FromHours(1))
Defensive patterns

Strategy: validation

Validate before calling

if (timeout <= TimeSpan.Zero || timeout.TotalMilliseconds > int.MaxValue) throw new ArgumentOutOfRangeException(nameof(timeout));

Try / catch

try { store.WithMaterializationTimeout(timeout); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == nameof(timeout)) { logger.LogError(ex, "Materialization timeout out of range"); throw; }

Prevention

When it happens

Trigger: Calling WithMaterializationTimeout with TimeSpan.Zero, a negative TimeSpan, or a TimeSpan whose TotalMilliseconds exceeds int.MaxValue (e.g. TimeSpan.MaxValue, TimeSpan.FromDays(30)).

Common situations: Trying to express 'no timeout' with TimeSpan.MaxValue or TimeSpan.FromMilliseconds(-1); copying a timeout constant defined for Task.Delay-style long waits.

Understand the failure class

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/091e688a094bfa69. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Radius/Secrets/RadiusSecretStoreExtensions.cs:286

    /// <param name="timeout">A positive materialization timeout, at most <see cref="int.MaxValue"/> milliseconds (~24.85 days).</param>
    /// <returns>The same store builder for chaining.</returns>
    /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeout"/> is not positive or exceeds the supported timer range.</exception>
    [Experimental("ASPIRERADIUS006", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
    [AspireExportIgnore(Reason = "Sealed-secret deploy-timing knob with no polyglot ATS equivalent.")]
    public static IResourceBuilder<RadiusSecretStoreResource> WithMaterializationTimeout(
        this IResourceBuilder<RadiusSecretStoreResource> store,
        TimeSpan timeout)
    {
        ArgumentNullException.ThrowIfNull(store);

        // The deploy path bounds materialization with CancellationTokenSource.CancelAfter, which
        // accepts at most int.MaxValue milliseconds (~24.85 days), and also adds this budget to
        // DateTimeOffset.UtcNow. A larger value (e.g. TimeSpan.MaxValue) would pass a "positive"
        // check yet throw ArgumentOutOfRangeException mid-deploy, so reject it here at configuration
        // time. See https://learn.microsoft.com/dotnet/api/system.threading.cancellationtokensource.cancelafter.
        if (timeout <= TimeSpan.Zero || timeout.TotalMilliseconds > int.MaxValue)
        {
            throw new ArgumentOutOfRangeException(
                nameof(timeout),
                timeout,
                "The materialization timeout must be positive and at most int.MaxValue milliseconds (~24.85 days).");
        }

        store.Resource.MaterializationTimeout = timeout;
        store.Resource.MaterializationTimeoutWasSet = true;
        return store;
    }

    // Validates every key without mutating the store's population, so a later invalid key cannot
    // leave the population partially assigned (which would then trip the ASPIRERADIUS065 guard on a
    // corrected retry). Returns the validated keys for the caller to commit atomically.
    private static List<string> ValidateKeys(string[] keys)
    {
        ArgumentNullException.ThrowIfNull(keys);
        foreach (var key in keys)
        {

View on GitHub (pinned to 25830f84bd)