Re: Generic semantics for the 400 status code

Willy Tarreau <> Fri, 15 July 2011 13:52 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id F3D4B21F8778 for <>; Fri, 15 Jul 2011 06:52:50 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -10.434
X-Spam-Status: No, score=-10.434 tagged_above=-999 required=5 tests=[AWL=0.165, BAYES_00=-2.599, RCVD_IN_DNSWL_HI=-8]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id J28J3rCi7heb for <>; Fri, 15 Jul 2011 06:52:50 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id 5D08B21F85FE for <>; Fri, 15 Jul 2011 06:52:50 -0700 (PDT)
Received: from lists by with local (Exim 4.69) (envelope-from <>) id 1QhioU-0001fz-Mg for; Fri, 15 Jul 2011 13:52:18 +0000
Received: from ([]) by with esmtp (Exim 4.69) (envelope-from <>) id 1QhioL-0001f3-Iw for; Fri, 15 Jul 2011 13:52:09 +0000
Received: from ([]) by with esmtp (Exim 4.72) (envelope-from <>) id 1QhioG-0008Fj-3E for; Fri, 15 Jul 2011 13:52:08 +0000
Received: (from willy@localhost) by mail.home.local (8.14.4/8.14.4/Submit) id p6FDpXuG027744; Fri, 15 Jul 2011 15:51:33 +0200
Date: Fri, 15 Jul 2011 15:51:33 +0200
From: Willy Tarreau <>
To: Mark Nottingham <>
Cc: HTTP Working Group <>
Message-ID: <>
References: <>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <>
User-Agent: Mutt/
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-1.9
X-W3C-Hub-Spam-Report: BAYES_00=-1.9, RP_MATCHES_RCVD=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001
X-W3C-Scan-Sig: 1QhioG-0008Fj-3E ab7fdf7ebb6ac53e8cf63d7d10e335ab
Subject: Re: Generic semantics for the 400 status code
Archived-At: <>
X-Mailing-List: <> archive/latest/10948
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>
Resent-Message-Id: <>
Resent-Date: Fri, 15 Jul 2011 13:52:18 +0000

Hi Mark,

On Fri, Jul 15, 2011 at 10:53:09PM +1000, Mark Nottingham wrote:
> When people have error states that don't cleanly fit into an existing status code, they're often encouraged to use 400 or 500, depending on whether the client or server were at fault, as they're the most "generic" status codes.
> 500's definition fits this:
> > 8.5.1.  500 Internal Server Error
> > 
> >    The server encountered an unexpected condition which prevented it
> >    from fulfilling the request.
> However, 400 is much more specific:
> > 8.4.1.  400 Bad Request
> > 
> >    The request could not be understood by the server due to malformed
> >    syntax.  The client SHOULD NOT repeat the request without
> >    modifications.
> I think the 400 definition needs to be broadened, so that people don't invent their own status codes, or misuse existing ones.
> E.g.,
> """
> The server can or will not process the request, due to a client error (e.g., malformed syntax).
> """
> Additionally, I think we should move the caution against retrying the request to the general 4xx section (8.4)*.
> Background:
> Thoughts?

I have mixed opinions on this point.

On the one hand, yes we said a server could use 503 + Retry-After for rate
shaping when it's overloaded. However in my opinion this is irrelevant to
the client and it might return that to any request during the overload
period. If the server is refusing to serve a client which is abusing, a 4xx
seems more appropriate, since the cause is this specific client, but I don't
see any existing one which fits the purpose.

I have a principle of always ensuring that a client cannot cause a server
to emit 5xx codes if the server is working correctly. This is important
for someone like me who spends a lot of time staring at gigs of logs,
because when you spot a 5xx, it means something is going wrong with the
server. The only exception I found to this was 501.

So my understanding has always been this :
  - if the request is rejected because of the client, 4xx
  - if the request is rejected regardless of the client, 5xx

The difference is important when intermediaries look at return codes.
Some might want to reduce connection pools to the server when they see
5xx. Some will declare a server down or failing when they see 5xx.

Anyway, in the discussion at the link above, I'm not even sure the user
needs to get a Retry-After : if the client is abusing its contract, then
we don't necessarily want to see him reconnect ASAP when the abuse is
over. Still it can make sense to define one 4xx for client abuse.

Just my 2 cents,