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

  1. 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.
  2. Increase the readiness probe timeout to accommodate slow starts.
  3. Verify the backing MCP server is running, healthy, and reachable by the Foundry Toolbox.
  4. 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

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.

Related errors


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)