ErrLookupBackground articles › NOT_FOUND error code: why tRPC, Harbor, Nacos and other libraries return 404 "not found" errors for resources that may still exist

NOT_FOUND error code: why tRPC, Harbor, Nacos and other libraries return 404 "not found" errors for resources that may still exist

"NOT_FOUND" is the error code a large family of libraries attach to the 404-equivalent condition: the resource named in the request could not be resolved. Developers meet it as tRPC's TRPCError NOT_FOUND ("No \"query\"-procedure on path ..."), Harbor's NotFound errors on artifacts, blobs and replication executions, shadcn's registry item lookups, Nacos agent/MCP-server version fetches, and scope-filtered model lookups in LobeHub, Dokploy, Medusa and RAGFlow. The single most important thing to know: the resource being missing is only one cause — the same error fires for stale ids, wrong ownership scope, version skew between client and server, and cases where libraries deliberately hide "exists but forbidden" behind a not-found response.

Distilled from 97 documented records across 11 repositories.

Background

NOT_FOUND sits at the application layer, not the transport layer: it is a semantic decision by the server that the requested entity does not resolve, mapped onto HTTP 404 or an equivalent structured error code. The typical producer is a lookup function — a repository `findById`, a config-store query, a registry catalog scan, a router path dispatch — that returns null/undefined/zero rows, after which the caller throws a typed error carrying the id, name, or path that failed. In tRPC this is the server-side cousin of a 404: `callProcedure` throws NOT_FOUND with `No "<type>"-procedure on path "<path>"` when the path doesn't exist or the procedure kind doesn't match. In Harbor it is an error code on a controller error (`artifact %s:%s not found`, `replication execution %d not found`) that maps to HTTP 404. In shadcn's registry loader it is a RegistryItemNotFoundError when an item name isn't declared in the resolved catalog.

From the caller's side the error is usually deterministic and terminal — nearly every record says "do not retry, refresh the id source instead." But the underlying meaning varies more than the message suggests. One large subgroup is the scope-filtered lookup: LobeHub, RAGFlow, Medusa and others construct their models with userId/workspaceId (or tenant) filters, so a resource owned by another user or workspace is indistinguishable from one that never existed. RAGFlow is explicit that this is deliberate — a single NotFound covers both "missing" and "forbidden" to avoid leaking other tenants' memories, and LobeHub's device guard does the same to prevent existence inference. ThingsBoard returns NOT_FOUND rather than FAILURE on bad provisioning credentials for the same anti-enumeration reason.

A second subgroup is timing races. Harbor's garbage collector reports "no blob found to mark delete failed" or "no blob item is updated to StatusNone" when the database row vanished between candidate selection and the status UPDATE — almost always overlapping GC executions or an external process deleting rows. More generally, any flow that lists resources and then acts on them by id (LobeHub briefs, knowledge bases, topics; Harbor tags) can hit NOT_FOUND when the row is deleted in between, and most libraries advise treating that branch as idempotent success.

Finally, NOT_FOUND often means "wrong shape of request," not "missing thing." tRPC throws it when client and server router shapes drifted after a rename or a version skew, or when a query path is called with `.mutate()`. shadcn throws "The item at ... was not found" when a local file path reaches the namespace-resolution branch instead of `loadRegistry()`. Harbor's replication-execution lookup filters by vendor type, so an id belonging to a different job kind also reports not found, and Nacos distinguishes agent-not-found from version-not-found when a version was never published or was pruned. The family's shared lesson: verify what identifier, scope, and shape the server actually resolves before concluding the resource is gone.

Common causes

What usually fixes it

Go deeper

Documented occurrences

…and 77 more across the corpus — use search.

Honest provenance: generated on 2026-08-27 from AI-assisted analysis of the linked records. See how records are made.