apache / apache/apisix

help request: native gRPC error mapping in traffic-shaping plugins (limit-conn, limit-req, limit-count)

Open
#13,333 1 comment 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Lua
Stars
17.1k
Forks
2.9k
Avg merge
3d 16h
Merged PRs (30d)
63

Description

### Description

Currently, when traffic-shaping plugins such as `limit-conn`, `limit-req`, or `limit-count` reject a request, they respond with a standard HTTP status code (e.g., `429 Too Many Requests`).
While this works for standard HTTP/REST traffic, it causes significant issues for gRPC clients. When a gRPC client receives a raw HTTP error with a non-200 status and text/HTML body, it cannot parse the response as a valid gRPC message. This leads to:
1. Client-side Protocol Errors: The client often falls back to a generic `Unavailable` or `Internal` error (e.g., "transport: received the unexpected content-type") instead of the actual reason.
2. Loss of Specificity: The client cannot distinguish between "Rate Limited" (`ResourceExhausted`) and "Server Down" (`Unavailable`).
3. Observability Gaps: Prometheus metrics based on the HTTP status code show a rejection, but gRPC-specified dashboards lose visibility into why the RPC failed.

### Workaround

To achieve protocol-compliant rejections and maintain observability, we have to implement a custom "post-processing" plugin with a very low priority. This plugin will catch rejections from other plugins and rewrite them during the `header_filter` & `body_filter` phases:
1. Set `ngx.status = 200`
2. Set `Content-Type: application/grpc`
3. Set `Content-Length: 0`
4. Set the appropriate HTTP status mapping for `grpc-status` and `grpc-message` headers
5. Ensure the response body is empty to satisfy the "Trailers-Only" gRPC requirement
---

I would like to inquire if there is an idiomatic or officially recommended way to handle protocol-compliant rejections for gRPC traffic within the existing APISIX architecture, or if this requirement should be considered as a candidate for a core feature enhancement to the traffic-shaping plugins.

### Environment

- APISIX version (run `apisix version`): 3.14.1
- Operating system (run `uname -a`): Linux
- OpenResty / Nginx version (run `openresty -V` or `nginx -V`): openresty/1.27.1.2
- etcd version, if relevant (run `curl http://127.0.0.1:9090/v1/server_info`):
- APISIX Dashboard version, if relevant:
- Plugin runner version, for issues related to plugin runners:
- LuaRocks version, for installation issues (run `luarocks --version`):

Contributor guide

Open the contributing guide

Research direction

Start by reading the limit-conn, limit-req, and limit-count plugin implementations and the rejection paths they use. Compare those paths with the header_filter and body_filter phases described in the workaround, then document whether APISIX has an existing gRPC error-mapping entry point or define the scope of a core enhancement.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua, nginx
Domain
api, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.