dotnet/reactive · error · TimeoutException
The operation has timed out.
Error message
The operation has timed out.
What it means
AsyncEnumerable.Timeout throws TimeoutException when the source does not produce its next element within the configured time window. Upon timeout the operator cancels the source (via its CancellationTokenSource) and schedules the enumerator's DisposeAsync before raising the exception.
Solutions
- Increase the timeout duration to a realistic bound for the slowest expected source emission.
- Fix the underlying source's latency (connection pooling, query tuning, retry with backoff).
- Catch TimeoutException and apply a fallback/restart strategy, e.g. .Catch((TimeoutException) => fallbackSequence).
- Ensure the source honors the CancellationToken passed so cancellation propagates promptly.
Example fix
// before
await foreach (var x in src.Timeout(TimeSpan.FromSeconds(1))) Consume(x);
// after
await foreach (var x in src
.Timeout(TimeSpan.FromSeconds(30))
.Catch<int, TimeoutException>(_ => AsyncEnumerable.Return(-1)))
Consume(x); Defensive patterns
Strategy: try-catch
Try / catch
try { await foreach (var x in src.Timeout(d)) ... }
catch (TimeoutException) { fallback(); } Prevention
- Size the timeout above worst-case source latency.
- Ensure the source honors cancellation tokens.
- Add .Catch<int, TimeoutException> fallbacks for resilience.
- Monitor upstream latency so timeouts aren't the first signal.
When it happens
Trigger: Enumerating AsyncEnumerable.Timeout(source, timeout, ...) (or WithTimeout) where a MoveNextAsync on the source exceeds the allowed duration; also when the delay task wins the race against the source's next element.
Common situations: Downstream services slow or hung (network latency, dead database connection); timeout value set too low for expected processing time; token/CTS misconfiguration causing source to ignore cancellation until after the deadline.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Value cannot be null. (Parameter 'cts')
- ArgumentNullException
- One or more errors occurred.
- Exception of type 'System.InvalidOperationException' was…
- Value cannot be null. (Parameter 'cts')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/06a447088fbcff1f.
Report an issue: GitHub.
Appendix: source
Thrown at Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Timeout.cs:144
if (winner == delay)
{
// NB: We still have to wait for the MoveNextAsync operation to complete before we can
// dispose _enumerator. The resulting task will be used by DisposeAsync. Also note
// that throwing an exception here causes a call to DisposeAsync, where we pick up
// the task prepared below.
// NB: Any exception reported by a timed out MoveNextAsync operation won't be reported
// to the caller, but the task's exception is not marked as observed, so unhandled
// exception handlers can still observe the exception.
// REVIEW: Should exceptions reported by a timed out MoveNextAsync operation come out
// when attempting to call DisposeAsync?
_loserTask = next.ContinueWith((_, state) => ((IAsyncDisposable)state!).DisposeAsync().AsTask(), _enumerator);
_sourceCTS!.Cancel();
throw new TimeoutException();
}
delayCts.Cancel();
}
if (await moveNext.ConfigureAwait(false))
{
_current = _enumerator.Current;
return true;
}
break;
}
await DisposeAsync().ConfigureAwait(false);
return false;
}
}View on GitHub (pinned to 94b5d5ab91)