Summary
GET /chunks/{address} answers 500 read chunk failed for a chunk the node cannot produce, where GET /bytes/{reference} and GET /feeds/{owner}/{topic} answer 404 for the equivalent condition. A 500 tells every HTTP client that the server is broken; here it usually means "I looked and did not find it", which a client should handle quite differently.
This is about which status code carries which meaning. It is not a request for Bee to prove that a chunk does not exist — see "What we are not asking for" below.
Observed
Bee 2.8.2 (2.8.2-7e703f4, API 8.1.1), a local bee-factory cluster:
| Request |
Condition |
Response |
GET /bytes/{ref} |
never uploaded |
404 |
GET /feeds/{owner}/{topic} |
feed has no updates |
404 {"code":404,"message":"lookup at failed"} |
GET /chunks/{addr} |
never uploaded |
500 {"code":500,"message":"read chunk failed"} |
GET /chunks/{addr} |
uploaded moments ago, not yet retrievable |
500 {"code":500,"message":"read chunk failed"} |
GET /chunks/{addr} |
uploaded, settled (about a second later) |
200 |
$ curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:1633/bytes/efef...efef
404
$ curl -s -w '\n%{http_code}\n' http://127.0.0.1:1633/feeds/19e7...ff2a/cdcd...cdcd
{"code":404,"message":"lookup at failed"}
404
$ curl -s -w '\n%{http_code}\n' http://127.0.0.1:1633/chunks/abab...abab
{"code":500,"message":"read chunk failed"}
500
Why it matters to a client
A client library cannot map these onto sensible behaviour without string-matching the message:
404 → the thing is not there; carry on, perhaps write it.
500 → the server is in trouble; surface an error, back off, do not treat this as data.
Because /chunks returns 500 for the ordinary "not found" case, a library must either treat some 500s as absence (and risk swallowing a real fault) or treat every 500 as a fault (and break on a perfectly normal missing chunk). We are writing an SDK that reads feed updates by index, where "no update at this index yet" is the expected answer most of the time, and we had to match on read chunk failed to get either behaviour right.
It is also inconsistent within Bee's own API: three endpoints, one underlying condition, two status codes.
Suggested
Distinguish what the node actually knows:
404 — retrieval completed and the chunk was not found. Matches /bytes and /feeds.
504 (or 503) — the retrieval attempt did not complete: timed out, no peers, upstream error.
500 — an internal error in the node itself.
The OpenAPI spec would need the same change, since it currently documents 404 for /chunks while the implementation returns 500.
What we are not asking for
Not a guarantee of absence. In a distributed store no node can prove a chunk was never written, and a 404 here would rightly mean "I did not find it", not "it does not exist". Clients that need "is this address free" have to solve that themselves, and we are doing so. The ask is only that "I looked and found nothing" and "something went wrong" stop sharing a status code.
One thing we have not pinned down
Immediately after an upload the same address answers 500 for roughly a second and then 200:
+0ms chunk=500 feed=404
+1000ms chunk=200 feed=200
Some addresses were readable at once and others were not, which makes us suspect it depends on whether the chunk's neighbourhood is the receiving node's own — that is, ordinary push-sync latency rather than a fault. We are not reporting that as a bug. It is relevant here only because it is another case that arrives as the same 500, and a client cannot tell it from a chunk that was never written.
Environment
Bee 2.8.2 (2.8.2-7e703f4, API 8.1.1) in a local bee-factory cluster, queen on 127.0.0.1:1633, immutable depth-20 batch on the dev chain. Seen from both @ethersphere/bee-js 13.0.0 and plain fetch.
Summary
GET /chunks/{address}answers500 read chunk failedfor a chunk the node cannot produce, whereGET /bytes/{reference}andGET /feeds/{owner}/{topic}answer404for the equivalent condition. A 500 tells every HTTP client that the server is broken; here it usually means "I looked and did not find it", which a client should handle quite differently.This is about which status code carries which meaning. It is not a request for Bee to prove that a chunk does not exist — see "What we are not asking for" below.
Observed
Bee 2.8.2 (
2.8.2-7e703f4, API 8.1.1), a local bee-factory cluster:GET /bytes/{ref}404GET /feeds/{owner}/{topic}404 {"code":404,"message":"lookup at failed"}GET /chunks/{addr}500 {"code":500,"message":"read chunk failed"}GET /chunks/{addr}500 {"code":500,"message":"read chunk failed"}GET /chunks/{addr}200Why it matters to a client
A client library cannot map these onto sensible behaviour without string-matching the message:
404→ the thing is not there; carry on, perhaps write it.500→ the server is in trouble; surface an error, back off, do not treat this as data.Because
/chunksreturns 500 for the ordinary "not found" case, a library must either treat some 500s as absence (and risk swallowing a real fault) or treat every 500 as a fault (and break on a perfectly normal missing chunk). We are writing an SDK that reads feed updates by index, where "no update at this index yet" is the expected answer most of the time, and we had to match onread chunk failedto get either behaviour right.It is also inconsistent within Bee's own API: three endpoints, one underlying condition, two status codes.
Suggested
Distinguish what the node actually knows:
404— retrieval completed and the chunk was not found. Matches/bytesand/feeds.504(or503) — the retrieval attempt did not complete: timed out, no peers, upstream error.500— an internal error in the node itself.The OpenAPI spec would need the same change, since it currently documents
404for/chunkswhile the implementation returns500.What we are not asking for
Not a guarantee of absence. In a distributed store no node can prove a chunk was never written, and a
404here would rightly mean "I did not find it", not "it does not exist". Clients that need "is this address free" have to solve that themselves, and we are doing so. The ask is only that "I looked and found nothing" and "something went wrong" stop sharing a status code.One thing we have not pinned down
Immediately after an upload the same address answers
500for roughly a second and then200:Some addresses were readable at once and others were not, which makes us suspect it depends on whether the chunk's neighbourhood is the receiving node's own — that is, ordinary push-sync latency rather than a fault. We are not reporting that as a bug. It is relevant here only because it is another case that arrives as the same
500, and a client cannot tell it from a chunk that was never written.Environment
Bee 2.8.2 (
2.8.2-7e703f4, API 8.1.1) in a local bee-factory cluster, queen on127.0.0.1:1633, immutable depth-20 batch on the dev chain. Seen from both@ethersphere/bee-js13.0.0 and plainfetch.