17

How do I configure nginx to return http status code 429 (Too Many Requests) instead of the default 503 (Service Unavailable) when throttling/rate limiting?

FYI, I'm using nginx as a reverse proxy with the HttpLimitReqModule. The draft spec for 429 status code is RFC6585.

This (closed) question on stackexchanged shows that it is possible to use the error_page directive. However, I don't want to return a 429 if there really is a server problem (not the customer hitting us too much) and the server should be returning 503 Service Unavailable.

Any suggestions?

adambrod
  • 283
  • 1
  • 2
  • 6
  • FYI, I've created an enhancement request for this feature as it isn't possible without mapping all 503s to 429s. – adambrod Mar 06 '13 at 14:55

3 Answers3

29

Good news, with Version 1.3.15 http://mailman.nginx.org/pipermail/nginx/2013-March/038306.html

we have the "limit_req_status" and "limit_conn_status" directives. I just tested them on Gentoo Linux (note that you need to have the modules limit_req and limit_con compiled in).

With these settings I think you can achieve what you've asked for:

limit_req_status 429;
limit_conn_status 429;

I have verified this with a quick:

ab2 -n 100000 -c 55 "http://127.0.0.1/api/v1

On which most request failed after activating the directive due to the high request rate and the configured limit in nginx:

limit_req zone=api burst=15 nodelay;
vanthome
  • 690
  • 5
  • 13
1

Based on VBart's response and other comments, it is clear that the best option is to map 503 errors to 429s.

error_page 503 = 429 /too-many-requests.html

Since nginx (1.3.x) only uses 503 status codes for limit_req and limit_conn, this should be a fine approach.

adambrod
  • 283
  • 1
  • 2
  • 6
  • this is *not* the best option. 429 is a specific use case, mapping all potential 503s (service unavailable) to return a 429 is misleading and invalid to users. For instance, a client might see a 429 and use a back-off retry logic, but if the 503 is unrelated to throttling it doesnt help. – Eddie Sep 27 '17 at 19:27
0

Nginx itself never returns 503 in cases other than limit_req and limit_conn.

VBart
  • 8,159
  • 3
  • 24
  • 25
  • 1
    Ah, that's interesting. So you're saying that if I replace 503 with 429 using error_page, I'll never be telling customers Too Many Requests unless they really are sending too many requests? – adambrod Mar 01 '13 at 15:06
  • Yes, true, but with only one exception, that you don't have `(proxy/factcgi/scgi/uwsgi)_intercept_errors` enabled. http://nginx.org/r/proxy_intercept_errors – VBart Mar 01 '13 at 15:17
  • 1
    It is also possible that the app served by nginx would return 503, which makes it hard for the client to see is it connection limit from nginx or server error from the app. – bbaja42 Jan 11 '16 at 11:43