microsoft/aspire · error · TimeoutException
Foundry Toolbox did not discover the required tools within
Error message
Foundry Toolbox did not discover the required tools within {_timeout}: {expected}. What it means
Thrown as a TimeoutException by WaitForToolsAsync when the required tools (tool names plus '{label}.*' patterns for MCP server labels) were not all discovered on the Toolbox within the probe timeout. The probe pages through tools/list until the expected set is complete; on expiry it reports what was still missing.
Solutions
- Compare the expected tool names/labels in code against the actual tools listed by the Toolbox (via the dashboard or a manual tools/list call) and fix mismatches.
- Increase the readiness probe timeout to accommodate slow starts.
- Verify the backing MCP server is running, healthy, and reachable by the Foundry Toolbox.
- Re-register the missing tool in the Toolbox configuration and redeploy.
Example fix
// before
.WithTools("search-tool") // server actually exposes 'web-search'
// after
.WithTools("web-search") // matches the tool name advertised by the MCP server Defensive patterns
Strategy: retry
Validate before calling
// Compare expected names against the live Toolbox before waiting: // var listed = await CallToolsListAsync(endpoint, token); // assert expected ⊆ listed
Try / catch
try
{
await probe.WaitForToolsAsync(accessToken, ct);
}
catch (TimeoutException ex)
{
logger.LogWarning(ex, "Tools not discovered in time; retrying once.");
await probe.WaitForToolsAsync(accessToken, ct);
} Prevention
- Verify expected tool names and MCP server labels match exactly what the server advertises.
- Size the probe timeout for cold starts and network latency.
- Ensure the backing MCP server is healthy and reachable before waiting on tools.
When it happens
Trigger: Calling .WaitForTools(...) where the Toolbox never exposes one or more of the required tool names or MCP-server-label tools before the timeout elapses — e.g. the backing MCP server is slow to start, not registered, or the tool name/label in code does not match what the server advertises.
Common situations: Typo in the expected tool name or McpServerLabel; the downstream MCP server crashed or is unreachable from Foundry; network latency or cold start exceeding the configured timeout; the tool list paginates slowly and the timeout is too short.
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
- Foundry Toolbox MCP initialization did not negotiate a…
- A discovered Toolbox tool did not have a name.
- The Toolbox MCP response did not contain JSON-RPC response…
- Toolbox MCP request failed
- -32603
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/4bc0bb3ccba093a5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Foundry/Toolbox/FoundryToolboxReadinessProbe.cs:122
(hasConfiguredExpectations || discoveredToolNames.Count > 0))
{
return discoveredToolNames.ToArray();
}
// Toolbox tool discovery is eventually consistent immediately after reconciliation.
await Task.Delay(_retryDelay, discoveryCancellation.Token).ConfigureAwait(false);
}
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
var expectedTools = requiredToolNames
.Concat(requiredMcpServerLabels.Select(label => $"{label}.*"))
.Order(StringComparer.Ordinal)
.ToArray();
var expected = expectedTools.Length == 0
? "any tool"
: string.Join(", ", expectedTools);
throw new TimeoutException(
$"Foundry Toolbox did not discover the required tools within {_timeout}: {expected}.");
}
}
private static string CreateToolsListPayload(int requestId, string? cursor)
{
using var stream = new MemoryStream();
using (var writer = new Utf8JsonWriter(stream))
{
writer.WriteStartObject();
writer.WriteString("jsonrpc", "2.0");
writer.WriteNumber("id", requestId);
writer.WriteString("method", "tools/list");
writer.WriteStartObject("params");
if (cursor is not null)
{
writer.WriteString("cursor", cursor);
}View on GitHub (pinned to 25830f84bd)