microsoft/aspire · error · TimeoutException
Timed out waiting for a tracked browser protocol response to
Error message
Timed out waiting for a tracked browser protocol response to '{method}'. What it means
SendCommandAsync registers a pending CDP command and awaits its response with a timeout. If the browser never replies within the window (and cancellation was not user- or dispose-driven), the OperationCanceledException is converted to this TimeoutException naming the CDP method that went unanswered.
Solutions
- Retry the operation; if it repeats, tear down and reacquire the browser lease/connection.
- Verify the browser process is alive and responsive.
- Confirm the target browser version supports the CDP method being sent.
- Increase the command timeout if the workload legitimately takes longer.
Example fix
// before
var target = await connection.CreateTargetAsync(url); // throws on transient stall
// after
try
{
var target = await connection.CreateTargetAsync(url);
}
catch (TimeoutException)
{
lease = await registry.AcquireAsync(config, ct); // reconnect and retry
} Defensive patterns
Strategy: retry
Validate before calling
// Check responsiveness cheaply before expensive CDP work
using var ping = await connection.SendCommandAsync("Browser.getVersion"); // or a Process.HasExited check on the browser process Try / catch
for (var attempt = 0; attempt < 2; attempt++)
{
try { return await connection.CreateTargetAsync(url); }
catch (TimeoutException) when (attempt == 0) { await ReacquireLeaseAsync(); }
} Prevention
- Bound CDP work with reasonable timeouts and retry once before rebuilding the connection.
- Monitor the browser process (HasExited) to detect hangs early.
- Verify browser versions support the CDP methods you send.
When it happens
Trigger: Sending any CDP command (Target.createTarget, Target.getTargets, Target.attachToTarget, Target.closeTarget, discovery/instrumentation enable calls) whose response never arrives: browser hung, renderer blocked, or browser silently dropped the command.
Common situations: Browser process frozen or under heavy load; overloaded CI container; browser version that does not implement the sent method (no response ever returned); transient pipe stall just under the disconnect threshold.
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
- Browser debug connection closed by the remote endpoint with…
- (CDP error ).
- Tracked browser host does not expose a WebSocket debug…
- Tracked browser protocol event method was not a string.
- Tracked browser protocol frame ended unexpectedly.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/671583df1160cbb1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Browsers/BrowserLogsCdpConnection.cs:266
_logger.LogTrace("Tracked browser protocol -> {Frame}", BrowserLogsCdpProtocol.DescribeFrame(payload));
await _sendLock.WaitAsync(sendCts.Token).ConfigureAwait(false);
try
{
// Browser-level CDP transports are serialized so startup, reconnect, screenshot, and shutdown never
// interleave command frames on the same connection.
await _transport.SendAsync(payload, sendCts.Token).ConfigureAwait(false);
}
finally
{
_sendLock.Release();
}
return await pendingCommand.Task.ConfigureAwait(false);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested && !_disposeCts.IsCancellationRequested)
{
throw new TimeoutException($"Timed out waiting for a tracked browser protocol response to '{method}'.");
}
finally
{
_pendingCommands.TryRemove(commandId, out _);
}
}
private async Task ReceiveLoopAsync()
{
Exception? terminalException = null;
try
{
while (!_disposeCts.IsCancellationRequested)
{
var frame = await _transport.ReceiveAsync(_disposeCts.Token).ConfigureAwait(false);
_logger.LogTrace("Tracked browser protocol <- {Frame}", BrowserLogsCdpProtocol.DescribeFrame(frame));
View on GitHub (pinned to 25830f84bd)