HTTP-to-GRPC status code mapping.. again

75 views
Skip to first unread message

Anton Pantuykhin

unread,
Jul 15, 2025, 9:06:29 AM7/15/25
to grpc.io
Hello! I know that this question is frequently discussed, but I was unable to find the current stance of the grpc team regarding it and also motivation behind some mappings. I understand that this table https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md is only used on the client side when no grpc-status is present but still looks like some mappings may not be the best.

1. 429 is mapped to UNAVAILABLE but not RESOURCE_EXHAUSTED. This comment has a small discussion about this: https://github.com/grpc/grpc/pull/4955#pullrequestreview-6858335 . However, it states that so while, yes, RESOURCE_EXHAUSTED could maybe also work, client handling here should be identical to UNAVAILABLE , I can't agree with that. Note, that UNAVAILABLE is the code client obviously want to retry (AIP also tells that: https://google.aip.dev/194#retryable-codes), while RE is the code you usually do not want to retry, because most of the time it is used by rate limiters to signal that server is overloaded (so adding retries will further amplify the load). Some clients may also retry RE, but the correct way to do this is to use much bigger timeout/backoff values than for UNAVAILABLE (for example, retry UNAVAILABLE after tens of milliseconds while RE after several seconds)

2. Why 404 is mapped to UNIMPLEMENTED ? This is because http2 (but not grpc) intermediary uses this code when method specified in the http2 path is not known and some routing fails ?

3. We often want to use exceptions to signal that method has failed however can be retried. This makes method handler's code much clear and simple, because exception handling can be done inside our framework/library. However, it's somehow difficult to determine which grpc status to use in such cases. UNKNOWN is recommended by docs for unhandled exceptions, however, it is usually non-retryable and also serves as a code for most of the http statuses when no grpc-status is present (i.e., most of intermediary errors will be retried if we configure grpc to retry UNKNOWN). INTERNAL also can not be used, because it may be emitted by both client and server. UNAVAILABLE probably is the best choice from the retries perspective, however it's semantics does not fit well.


Reply all
Reply to author
Forward
0 new messages