PrefectHQ/fastmcp · error · MCPError

-32000

-32000

Error message

Tool '{self.name}' execution timed out after {self.timeout}s

What it means

When a tool execution exceeds its configured timeout, _run_body catches the anyio TimeoutError and re-raises it as an MCPError with code -32000 and a message naming the tool and the timeout value. This turns a low-level cancellation into a protocol-level error clients can recognize.

Source

Thrown at fastmcp_slim/fastmcp/tools/function_tool.py:425

        arguments: dict[str, Any],
        *,
        strict: bool,
    ) -> Any:
        """Validate arguments and execute the body, applying any timeout."""
        try:
            if self.timeout is not None:
                try:
                    with anyio.fail_after(self.timeout):
                        result = await self._execute(
                            type_adapter, exec_is_async, arguments, strict=strict
                        )
                except TimeoutError:
                    logger.warning(
                        f"Tool '{self.name}' timed out after {self.timeout}s. "
                        f"Consider using task=True for long-running operations. "
                        f"See https://gofastmcp.com/servers/tasks"
                    )
                    raise MCPError(
                        code=-32000,
                        message=f"Tool '{self.name}' execution timed out after {self.timeout}s",
                    ) from None
            else:
                result = await self._execute(
                    type_adapter, exec_is_async, arguments, strict=strict
                )
        except PydanticValidationError as e:
            # Body errors are re-raised as _ToolBodyError, so a bare pydantic
            # ValidationError here is an argument-validation failure (a bad call).
            # Convert it to fastmcp's ValidationError so the middleware chain and
            # downstream error taxonomy (e.g. Sentry filters) can treat it as a
            # client error rather than a server bug.
            raise ValidationError(str(e), log_level=logging.WARNING) from e
        except _ToolBodyError as e:
            # The tool's own body raised a pydantic ValidationError. Surface the
            # original so it is treated as a server-side error, hiding the
            # internal sentinel while preserving the error's own chained cause.

View on GitHub (pinned to 1f02114297)

Solutions

  1. Increase tool.timeout to accommodate realistic execution time
  2. Optimize the tool body (cache, pagination, async I/O instead of blocking calls)
  3. Run the call with task=True as a background task for long-running operations
  4. Handle MCPError code -32000 client-side with retry/backoff if the operation is transiently slow

Example fix

// before
FunctionTool.from_function(slow_api_call, timeout=2.0)
// after
FunctionTool.from_function(slow_api_call, timeout=30.0)
// or for long ops:
await client.call_tool("slow_api_call", {...}, task=True)
Defensive patterns

Strategy: try-catch

Validate before calling

# before calling, ensure the operation fits the budget
import time
t0 = time.monotonic()
probe = quick_health_check()  # optional precheck
if time.monotonic() - t0 > tool.timeout * 0.5:
    raise RuntimeError('downstream too slow for tool timeout')

Try / catch

from mcp.types import McpError
try:
    result = await client.call_tool('my_tool', args)
except McpError as e:
    if e.error.code == -32000 and 'timed out' in e.error.message:
        result = await retry_with_backoff(lambda: client.call_tool('my_tool', args))

Prevention

When it happens

Trigger: Calling tool.run()/calling the tool with arguments whose execution time exceeds tool.timeout; sync functions dispatched to a worker thread (or async functions) that block or take longer than the configured timeout.

Common situations: Slow downstream HTTP calls or DB queries inside a tool; large inputs causing long computation; timeout set optimistically low; forgetting the suggested task=True pattern for long-running work.

Understand the failure class

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/f934a1f35cba4626. Report an issue: GitHub.