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
- 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
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
- 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
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- ASPIRERADIUS042
- ASPIRERADIUS046
- ASPIRERADIUS067
- A ConfigureRadiusInfrastructure callback changed the value…
- ASPIRERADIUS040
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)