Change the Delegated Routing V1 HTTP API server recommendation to return HTTP status code 200 (OK) with empty results instead of 404 (Not Found) when no matching records are found. This improves semantic correctness, prevents unwanted browser console errors, and provides separate guidance for servers and clients - with clients required to handle both response codes for backward compatibility, resiliency, and maximal interoperability with different server implementations.
The current Delegated Routing V1 HTTP API specification requires servers to return HTTP 404 (Not Found) when no matching records are found for a query. This creates two significant problems:
Browser Console Errors: When routing queries are made from web browsers and return 404s, browsers log error messages to the console that cannot be prevented programmatically. These error messages confuse users who understandably think something is broken, when in reality an empty result is a normal and expected outcome for many queries.
Semantic Incorrectness: HTTP 404 means "the requested resource does not exist." However, when querying /routing/v1/providers/{cid}, the endpoint itself exists and is functioning correctly - it simply found no results. Returning 404 conflates "endpoint not found" with "no data found," which are fundamentally different conditions.
As noted in the original issue, querying for a peer with specific filters demonstrates this problem clearly:
Update the following sections in specs/src/routing/http-routing-v1.md:
Current:
404 (Not Found): must be returned if no matching records are found.New:
200 (OK): the response body contains 0 or more records.404 (Not Found): SHOULD NOT be returned by a server, but if a client receives it, it MUST be interpreted as 200 with 0 results for backward compatibility, resiliency, and maximal interoperability.Current:
404 (Not Found): must be returned if no matching records are found.New:
200 (OK): the response body contains 0 or more peer records.404 (Not Found): SHOULD NOT be returned by a server, but if a client receives it, it MUST be interpreted as 200 with 0 results for backward compatibility, resiliency, and maximal interoperability.Current:
404 (Not Found): must be returned if no matching records are found.New:
200 (OK): the response body contains the IPNS Record for the given IPNS Name with Content-Type: application/vnd.ipfs.ipns-record. Any other content type MUST be interpreted as "no record found".404 (Not Found): SHOULD NOT be returned by a server, but if a client receives it, it MUST be interpreted as "no record found" for backward compatibility, resiliency, and maximal interoperability.For JSON responses (application/json):
{
"Providers": []
}
or
{
"Peers": []
}
For NDJSON streaming responses (application/x-ndjson):
For IPNS responses:
Content-Type: application/vnd.ipfs.ipns-record indicates a valid IPNS record was foundtext/plain with error message) MUST be interpreted as "no record found"The existing cache control behavior remains unchanged:
Research into REST API design patterns shows that returning 200 with empty collections is a common and recommended practice:
The HTTP specification defines status codes with specific meanings:
For collection/search endpoints, the resource is the endpoint itself, not the data it returns. The endpoint exists and functions correctly regardless of whether it finds matching data.
Cleaner Browser Console: Web applications will no longer show error messages for normal operations, reducing user confusion and support requests.
Clearer Semantics: Developers can distinguish between "endpoint doesn't exist" (real 404) and "no results found" (200 with empty data).
Consistent Response Structure: Clients can use the same parsing logic whether results are empty or populated.
This change is designed to be fully backward compatible by following the robustness principle - "be conservative in what you send, and liberal in what you accept":
This approach ensures maximum interoperability across the ecosystem while gradually transitioning to the semantically correct behavior.
Phase 1: Update server implementations to return 200
Phase 2: Update clients to have regression tests that ensure they handle both 200 and 404
This change has no security implications. It only affects the HTTP status code returned for empty results, not the data format, authentication, or authorization mechanisms.
Considered but rejected for the following reasons:
Rejected because:
Rejected in favor of in-place upgrade because:
Implementations should test the following scenarios:
Providers endpoint with no results:
GET /routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
Response: 200 OK
Body: {"Providers": []}
NDJSON streaming with no results:
GET /routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi
Accept: application/x-ndjson
Response: 200 OK
Content-Type: application/x-ndjson
Body: [empty - no lines]
IPNS endpoint with no results:
GET /routing/v1/ipns/k51qzi5uqu5dhlbegona8wfyei6jnjuhrulz3t8femxtfmak9134qpqncw3poc
Accept: application/vnd.ipfs.ipns-record
Response: 200 OK
Content-Type: text/plain; charset=utf-8
Body: delegate error: routing: not found
Note: The Content-Type is NOT application/vnd.ipfs.ipns-record, which indicates no record was found and parsing of body can be skipped. In this example, the body contains text/plain error message for convenience.
Clients MUST correctly handle:
Copyright and related rights waived via CC0.
We gratefully acknowledge the following individuals for their valuable contributions, ranging from minor suggestions to major insights, which have shaped and improved this specification.