Google cloud load balancer custom http header is missing

Data

After a lot of testing, these are the results I've come up with:

  1. The Google Cloud HTTPS Load Balancer does transfer custom HTTP headers to the backend service.
  2. However, it changes them to lower-case.

So, in your case, X-Custom-Header is transformed to x-custom-header.

Solution

  1. Simply change your code to read the lower-case version of your custom HTTP header. This is a simple fix, but one which may not be supported in the long-term by Google (there's not a word on this in Google's documentation so it's subject to change with no notice).
  2. Petition Google to change this idiosyncratic behaviour or at the very least mention it clearly in their documentation.

A little extra

As far as I know, the RFC 2047 which specified the X- prefix for custom HTTP headers and propagated the pseudo-standard of a capital letter for each word has been deprecated and replaced by RFC 6648 which recommends against the X- prefix in general and mentions nothing regarding the rest of the words in the custom HTTP header key name. If I were Google, I would change this behaviour to pass custom HTTP headers as is and let developers deal with the strings as they've set them.


The RFC (RFC 7230) for HTTP/1.1 Message Syntax and Routing says that header fields have a case-insensitive field name. If you're relying on case to match the header that doesn't align with the RFC.

Way back in the day I looked through either the Tomcat of Jetty source and they worked with everything as a .toLower().

Go has a CanonicalMIMEHeaderKey where it'll format the headers in a common way to be sure everything is on the same page.

Python still harkens back to the RFC822 (hg.python.org/cpython/file/2.7/Lib/rfc822.py#l211) days, but it forces a .lower() on headers to standardize.

Basically though what the GCP HTTP(S) Load Balancer is doing is acceptable as far as the RFC is concerned.