PrefectHQ/fastmcp · error · NotFoundError
Unknown resource: {uri!r} version {version!r}
Error message
Unknown resource: {uri!r} version {version!r} What it means
FastMCP raises NotFoundError("Unknown resource: {uri!r} version {version!r}") when a URI resolves but the specifically requested version does not exist. Raised by read_resource when get_resource_template(uri, version=...) returns None and a non-None version was supplied.
Source
Thrown at fastmcp_slim/fastmcp/server/server.py:1665
if is_timeout_error(e):
raise ResourceError(
"Upstream request timed out, please retry"
) from e
# Standard masking logic
if self._mask_error_details:
raise ResourceError(
f"Error reading resource {uri!r}"
) from e
raise ResourceError(
f"Error reading resource {uri!r}: {e}"
) from e
# Try templates (transforms + auth via get_resource_template)
template = await self.get_resource_template(uri, version=version)
if template is None:
if version is None:
raise NotFoundError(f"Unknown resource: {uri!r}")
raise NotFoundError(
f"Unknown resource: {uri!r} version {version!r}"
)
span.set_attributes(template.get_span_attributes())
params = template.matches(uri)
assert params is not None
# Path-security screening: reject traversal / absolute-path /
# null-byte payloads in extracted parameter values BEFORE the
# handler runs. This is the single chokepoint for every
# templated read (local decorator and provider-sourced), so
# enforcement lives here rather than in any decorator.
security = template.resolve_security(self._resource_security)
if security is not None:
failed = security.validate(params)
if failed is not None:
logger.debug(
"Rejected resource %r: parameter %r failed "
"path-security screening",View on GitHub (pinned to 1f02114297)
Solutions
- Enumerate available versions for the resource and use one that exists.
- Omit the version parameter to get the highest/default version.
- Register the requested version or fix the version string (typos like 'v2' vs '2.0').
- If pinning clients to versions, ensure deployments keep those versions registered.
Example fix
// before
res = await server.read_resource("data://report", version="3")
// after
versions = [t.version for t in await server.get_resource_templates()]
res = await server.read_resource("data://report", version=versions[0]) # or drop version= Defensive patterns
Strategy: validation
Validate before calling
# discover versions before pinning templates = await client.list_resource_templates() print([(t.uri_template, getattr(t, 'versions', None)) for t in templates])
Try / catch
try:
result = await server.read_resource(uri, version=v)
except NotFoundError as e:
if 'version' in str(e):
result = await server.read_resource(uri) # fall back to default version Prevention
- Avoid hardcoding version strings; discover them at runtime or drop the version param.
- Keep client-pinned versions in sync with server deployments.
- Use consistent version formatting across server and clients.
- Re-register retired versions temporarily during migrations.
When it happens
Trigger: `read_resource(uri, version="2.0")` (or a versioned client request via _version_request_meta) where the resource/template exists only under another version, or was never versioned at all.
Common situations: After a server upgrade that renamed/retired versions; hardcoded version strings in clients; mistyped version specifiers; mixing version-pinned clients with unversioned servers.
Related errors
- Unknown resource: {uri!r}
- Resource {uri!r} version {version!r} not found
- Unsupported content type: {type(item)}
- Remote server returned empty content for {parameterized_uri}
- Error reading resource {uri!r}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/5f35f55dbdcbc788.
Report an issue: GitHub.