Subject: 503, 403 & Retry-After: enforcing a limit on the number of requests allowed

From: Hugo Haas <[email-masked]>
Date: Wed, 06 Feb 2008 11:04:44 -0800

I've been wondering about the response code to use for enforcing a limit 
on the number of requests allowed.

Say I allow 10 requests per minute from a certain IP address. After 20 
seconds, my server receives an 11th request from a client and needs to 
reject it, as advertised to the client.

503 ("The server is currently unable to handle the request due to a 
temporary overloading or maintenance of the server.") is tempting 
because of the Retry-After header: the server can tell the client to try 
again in 40 seconds. However, the server has not really failed to 
process the request, it *chose* not to process it, because the client 
did something it should not have done.

So using a 5xx error code seems wrong, and a 4xx response more 
appropriate: the client was told not to do more than 10 requests a 
minute, but sent an 11th one, and therefore it's its fault that the 
request is not processed by the server which is behaving perfectly 
normally from that POV.

403 could work ("The server understood the request, but is refusing to 
fulfill it."). However 403 implies that "the request SHOULD NOT be 
repeated". Moreover, the Retry-After header is not defined for 4xx 
response codes as per section 14.37 to hint that the request could be 
repeated, and tell the client when it is acceptable to retry the 
request. So it's not very well suited.

So the options I see today are:
- use a server error (503) along with the Retry-After header
- use a client error (403), and convey when the request can be retried 
in the entity body (which is sub-optimal)

A better solution would be to allow Retry-After on a 403, with the 
meaning that the request can be retried at a later point, as indicated.

Cheers,

Hugo

---

From: Henrik Nordström <[email-masked]>
Date: Fri, 08 Feb 2008 16:18:17 +0100

> did something it should not have done.

Well, the request was correctly formed and only rejected because of the
preference of the server to not process that request at the moment so
5xx is the proper family to select from I think. The client do not need
to change the request in any manner to complete the request, just wait
and try again when the server condition have cleared.

and 503 is the closest among the defined ones as you point out.

Additionally the specs do not define how a server is to define
"overload", and imho a client sending more than the allocated share of
requests/s pretty well qualifies as the client has overloaded it's share
of the server resources.

403 is not suitable as it's a permanent error saying you are not allowed
to perform this action on the requested resource under any conditions.
Pointless to retry.

Regards
Henrik