Skip to main content

MCP Error Codes

Error Hierarchy

Base Error Classes

McpError (Abstract)

Base class for all MCP-related errors.

PublicMcpError

Errors safe to expose to clients (validation errors, not found, etc.).

InternalMcpError

Errors that should NOT expose details (server errors, unexpected failures).

Error Categories

Tool & Prompt Errors

ToolNotFoundError, ToolExecutionError, PromptNotFoundError, PromptExecutionError

Resource Errors

ResourceNotFoundError, ResourceReadError, InvalidResourceUriError

Validation Errors

InvalidInputError, InvalidOutputError, InvalidMethodError, MissingPromptArgumentError

Auth Errors

UnauthorizedError, AuthConfigurationError, SessionMissingError, AuthorizationRequiredError

Agent Errors

AgentNotFoundError, AgentExecutionError, AgentLoopExceededError, AgentTimeoutError

Rate Limit Errors

RateLimitError, QuotaExceededError

Transport Errors

TransportNotConnectedError, UnsupportedContentTypeError

Remote Errors

RemoteConnectionError, RemoteTimeoutError, RemoteToolNotFoundError

Elicitation Errors

ElicitationNotSupportedError, ElicitationTimeoutError, ElicitationFallbackRequired

Provider Errors

ProviderNotRegisteredError, DependencyCycleError, ProviderConstructionError

Registry Errors

RegistryDefinitionNotFoundError, FlowNotRegisteredError, EntryValidationError

Decorator Errors

InvalidDecoratorMetadataError, HookTargetNotDefinedError

Normalization Errors

MissingProvideError, InvalidUseClassError, InvalidEntityError

SDK Errors

FlowExitedWithoutOutputError, ServerNotFoundError, ConfigNotFoundError

Auth Internal Errors

EncryptionContextNotSetError, VaultLoadError, TokenLeakDetectedError

ESM Errors

EsmPackageLoadError, EsmVersionResolutionError, EsmManifestInvalidError, EsmCacheError, EsmRegistryAuthError, EsmInvalidSpecifierError

Usage Patterns

Throwing Errors

Using fail()

Error with Details

Custom toJsonRpcError

Some errors override toJsonRpcError() for custom data:

How Entry Errors Reach the Client

The same rules apply to tools, resources and prompts, whether the error is thrown or passed to this.fail():
  • Public errors pass through. A PublicMcpError (or subclass, such as InvalidInputError or ResourceNotFoundError) and an authorities refusal reach the client with their own message and code.
  • Anything else is wrapped in ToolExecutionError, ResourceReadError or PromptExecutionError. In production the client sees only the generic message with the errorId.
  • Every failure is logged once, with the same errorId the client sees and the error code. For an error the SDK wrapped, the logged message includes the original error’s message and stack in every environment; the stack of the reported error itself is logged in development only.
Two predicates exported from @frontmcp/sdk apply the same rules in code that catches errors around entries, such as hooks:
  • isClientFacingError(error: unknown): boolean is true for a public error (PublicMcpError or a subclass) and for an authorities refusal (AuthorityDeniedError). The flows pass these on unwrapped.
  • isMrtrSignal(error: unknown): error is InputRequiredSignal | MissingClientCapabilityError is true for the two signals the 2026-07-28 dispatcher answers itself: an input_required result and a -32021 error. Rethrow them instead of reporting them as failures.
tools/call answers with a result that has isError: true and _meta.code / _meta.errorId. resources/read and prompts/get answer with a JSON-RPC error. Its code comes from the error’s toJsonRpcError() when it has one; otherwise it depends on statusCode: data carries the errorId and code. An error with its own toJsonRpcError() keeps its data, with the errorId added. Under protocol 2026-07-28, -32002 (resource not found) is sent as -32602.

Error Properties

Best Practices

Use Specific Error Classes

Preserve Original Errors

Don’t Expose Internal Details

A generated error ID is err_ followed by 16 hex characters (8 random bytes).

Use Error IDs for Tracking

FrontMCP already logs each failed tool call, resource read and prompt with its errorId. Log it yourself when you handle an error in your own code:

Import