141

I have not found any specification about whether duplicate HTTP response headers are allowed by the standard, but I need to know if this will cause compatibility issues.

Say I have a response header like this:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.4; JBoss-4.0.3SP1 (build: CVSTag=JBoss_4_0_3_SP1 date=200510231054)/Tomcat-5.5
Cache-Control: no-cache
Cache-Control: no-store
Location: http://localhost:9876/foo.bar
Content-Language: en-US
Content-Length: 0
Date: Mon, 06 Dec 2010 21:18:26 GMT

Notice that there are two Cache-Control headers with different values. Do browsers always treat them as if they are written like "Cache-Control: no-cache, no-store"?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Su Zhang
  • 2,155
  • 2
  • 14
  • 11

2 Answers2

184

Yes

HTTP RFC2616 available here says:

Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]. It MUST be possible to combine the multiple header fields into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma. The order in which header fields with the same field-name are received is therefore significant to the interpretation of the combined field value, and thus a proxy MUST NOT change the order of these field values when a message is forwarded

So, multiple headers with the same name is ok (www-authenticate is such a case) if the entire field-value is defined as a comma-separated list of values.

Cache-control is documented here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 like this:

Cache-Control   = "Cache-Control" ":" 1#cache-directive

The #1cache-directive syntax defines a list of at least one cache-directive elements (see here for the formal definition of #values: Notational Conventions and Generic Grammar)

So, yes,

Cache-Control: no-cache, no-store

is equivalent to (order is important)

Cache-Control: no-cache
Cache-Control: no-store
mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • 2
    Thank you for your quick response, Simon! But doesn't the quoted paragraph from RFC 2616 apply to Cache-Control as well? Am I missing something? – Su Zhang Dec 06 '10 at 22:38
  • 1
    Almost 100% correct. Cache Control allows for multiple values: `Cache-Control = "Cache-Control" ":" 1#cache-directive`. Notice the `#` before `cache-directive`. That indicates multiple values are accepted (right from your definition above)... – ircmaxell Aug 29 '12 at 15:03
  • So "Cache-Control: no-cache" + "Cache-Control: no-store" = "Cache-Control: no-cache, no-store" but what if the same value were repeated, for example, "Cache-Control: no-cache, no-store" + "Cache-Control: no-cache" =?= "Cache-Control: no-cache, no-store, no-cache" or is it still the same? – jacobq Aug 21 '13 at 14:50
  • @iX3 - I don't think this is explicitly documented. Seems like an incorrect header setup to me. – Simon Mourier Aug 21 '13 at 21:22
  • 3
    "if and only if the entire field-value for that header field is defined as a comma-separated list" -- that to me sounds like the multiple values *must* be defined as a comma-separated list, i.e., they can't be split out as separate headers. – mpen Jan 23 '14 at 21:45
  • 2
    @mark - "defined as a comma-separated list" here means "defined in the BNF grammar as a comma-separated list". The Cache-control fields is indeed defined like that (x#blahblah). – Simon Mourier Jan 24 '14 at 00:09
  • 1
    @SimonMourier: Oh... I was reading that wrong. I getchya now. Thanks :-) – mpen Jan 24 '14 at 01:14
  • How about custom headers? – Yang Bo Jan 15 '16 at 06:36
  • does `My-Custom-Header: my-value-0\r\n My-Custom-Header: my-value-1\r\n` Equal to `My-Custom-Header: my-value-0, my-value-1\r\n` ? – Yang Bo Jan 15 '16 at 06:40
  • Since this is not standard, no-one should read/write/understand it (but you), so you can define how it works. However, I suppose some proxies or middleware systems, APIs, etc. could fail at passing it multiple times since they don't know it, so I would keep it as one line. – Simon Mourier Jan 15 '16 at 06:46
  • 2
    The section in the newer RFC 7230 that talks about handling multiple headers is https://tools.ietf.org/html/rfc7230#section-3.2.2 – Matthew Buckett Dec 07 '19 at 07:46
2

Note that the HSTS RFC6797 contradicts the RFC2616 (violating the "if and only if" language) by defining the behavior for multiple instances of the STS header, though it is not populated with comma-separated values:

  "If a UA receives more than one STS header field in an HTTP
  response message over secure transport, then the UA MUST process
  only the first such header field."
PosterBoy
  • 21
  • 1
  • 3
    Incorrect. RFC6797 does NOT define the STS header as containing a comma-separated list. So the "if and only if" rule from RFC 2616 applies just the same (meaning that multiple STS headers are NOT allowed as the STS header is not defined as taking a comma-separated list). RFC6797 just makes it non-deterministic what the consequences are of violating that rule, something that RFC2616 seems to leave open. – Frans Mar 07 '20 at 08:54