microsoft/aspire · error · TimeoutException
Callback ' ' timed out after s
Error message
Callback '{callbackId}' timed out after {s_callbackTimeout.TotalSeconds}s What it means
When invoking a client callback, JsonRpcCallbackInvoker wraps the call in a linked CancellationTokenSource with a fixed timeout (s_callbackTimeout). If the client does not respond before that timeout (and the caller's own token was not cancelled), the OperationCanceledException is converted into this TimeoutException naming the callback id and timeout in seconds.
Solutions
- Verify the client actually implements and responds to the given callbackId and return promptly.
- Check the client for blocking work (sync-over-async, locks, debugger pauses) on its RPC handler thread.
- Increase responsiveness or move long work off the callback path; acknowledge quickly then process async if the protocol allows.
- Catch TimeoutException on the caller side and degrade gracefully or retry if the callback is best-effort.
Example fix
// before
var result = await callbackInvoker.InvokeAsync<bool>("confirmDeploy", args); // hangs then times out
// after
try
{
var result = await callbackInvoker.InvokeAsync<bool>("confirmDeploy", args);
}
catch (TimeoutException)
{
// fall back to default behavior when the client is unresponsive
var result = false;
} Defensive patterns
Strategy: try-catch
Try / catch
try { await invoker.InvokeAsync<TResult>(callbackId, args, ct); }
catch (TimeoutException) { /* fallback/default behavior or retry */ } Prevention
- Keep client callback handlers fast; return quickly and defer heavy work.
- Never block the client RPC dispatch thread (no sync-over-async, no locks held across awaits).
- Log callback start/finish on the client to spot slow handlers before they time out.
When it happens
Trigger: Calling callbackInvoker.InvokeAsync<TResult>(callbackId, args) where the connected client never replies to the 'invokeCallback' request within s_callbackTimeout seconds, or is blocked/slow handling it.
Common situations: Client stuck processing a long-running UI operation; client event loop blocked by a synchronous wait; client hung or paused (debugger breakpoint); network/pipe congestion delaying the response; client not handling that callbackId at all.
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
- Callback not found
- No client connection available for callback invocation
- -32602
- A ConfigureRadiusInfrastructure callback changed the value…
- A discovered Toolbox tool did not have a name.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/4df74ebe3e74cf12.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.RemoteHost/JsonRpcCallbackInvoker.cs:50
{
if (_clientRpc == null)
{
throw new InvalidOperationException("No client connection available for callback invocation");
}
using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(s_callbackTimeout);
try
{
return await _clientRpc.InvokeWithCancellationAsync<TResult>(
"invokeCallback",
[callbackId, args],
cts.Token).ConfigureAwait(false);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
throw new TimeoutException($"Callback '{callbackId}' timed out after {s_callbackTimeout.TotalSeconds}s");
}
}
/// <inheritdoc />
public async Task InvokeAsync(string callbackId, JsonNode? args, CancellationToken cancellationToken = default)
{
await InvokeAsync<object?>(callbackId, args, cancellationToken).ConfigureAwait(false);
}
}
View on GitHub (pinned to 25830f84bd)