106

I had a problem with a custom HTTP SESSION_ID header not being transfered by nginx proxy.

I was told that underscores are prohibited according to the HTTP RFC.

Searching, I found that most servers like Apache or nginx define them as illegal in RFC2616 section 4.2, which says:

follow the same generic format as that given in Section 3.1 of RFC 822 [9]

RFC822 says:

The field-name must be composed of printable ASCII characters (i.e., characters that have values between 33. and 126., decimal, except colon)

Underscore is decimal character 95 in the ASCII table in the 33-126 range.

What am I missing?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
white
  • 1,823
  • 2
  • 12
  • 20

2 Answers2

189

They are not forbidden, it's CGI legacy. See "Missing (disappearing) HTTP Headers".

If you do not explicitly set underscores_in_headers on;, nginx will silently drop HTTP headers with underscores (which are perfectly valid according to the HTTP standard). This is done in order to prevent ambiguities when mapping headers to CGI variables, as both dashes and underscores are mapped to underscores during that process.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Alexey Ten
  • 13,794
  • 6
  • 44
  • 54
  • 36
    Just spent hours debugging why my rails app works fine in development but not on production because of this :/ – Qwertie Aug 30 '17 at 00:49
  • 17
    Just spent hours debugging why my NodeJS app works fine in development but not on production because of this :/ – jujule Sep 24 '20 at 22:00
  • 9
    Just spent hours debugging why my Flask app works fine in development but not on production because of this :/ – SilverTear Aug 09 '21 at 04:29
  • Link to answer for Apache: https://stackoverflow.com/questions/17440564/all-caps-http-headers-with-underscores-dropped-in-apache-2-4 – jumpjack Sep 24 '21 at 08:21
  • 8
    Just spent 5 minutes debugging why my flask app doesnt work in dev or production and then thankfully stumbled upon this thread. Phew, dodged a bullet. – joidegn Sep 30 '21 at 09:28
  • 1
    Just spend days checking why app works locally but not in prod (kubernetes with nginx ingress) – faron Mar 21 '22 at 13:10
  • 1
    I spent a full 10 days to find this solution, because Google didn't find good answers to "nginx removes request headers". – rawcode Jun 15 '22 at 07:16
  • I spent all morning debugging why it works on flask server but not AWS – harveyslash Oct 04 '22 at 17:21
  • just spent hours on this. – manit Mar 31 '23 at 16:58
  • Just spent hours debugging why my Mendix app works fine in development but not on production because of this :/ – S. Bruijnis Jul 28 '23 at 12:25
  • nginx is hard to use and this is the last straw. I think I'm gonna quit using it. Who in their right mind makes a web server with proxy-pass and drops headers? I think Nginx must be overrated. I'm gonna make a new one or just stick with Node or something like Bun, at least, that's what I want to do. – user3413723 Aug 10 '23 at 17:49
  • 1
    @user3413723 wish you the best – Alexey Ten Aug 10 '23 at 17:51
27

Underscores in header fields are allowed per RFC 7230, sec. 3.2., but are uncommon.

Community
  • 1
  • 1
Julian Reschke
  • 40,156
  • 8
  • 95
  • 98