75

As far as I know it is allowed by the HTTP spec to set more than one HTTP header with the same name. Is there any use case to do so (from client to server and vice versa)?

HTTP 1.1 Section 4.2:

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.

If I'm not wrong there is no case where multiple headers with the same name are needed.

deamon
  • 89,107
  • 111
  • 320
  • 448
  • 3
    "If I'm not wrong there is no case where multiple headers with the same name are needed." -- You're correct, and its not something I'd bank on being properly supported depending on what technologies are sitting between you and the raw headers. – heisenberg Jul 14 '10 at 13:12
  • 9
    The only time I've seen the duplicate headers is for `Set-Cookie:`. – TRiG Apr 28 '11 at 16:10
  • 2
    Related question: [Are Duplicate HTTP Response Headers acceptable?](http://stackoverflow.com/questions/4371328/are-duplicate-http-response-headers-acceptable). WebDAV headers are [another example](https://github.com/joyent/node/issues/2750) of header name duplicates. – chrisjleu Dec 14 '14 at 10:44
  • Actually, you cannot pass a comma-separated list of values in a single header name for k8s auth proxy! The reason for that is because k8s supports commas for RBAC resource names (for some ungodly reason; legacy bug/oversight that became entrenched most likely). – mecampbellsoup Aug 03 '23 at 03:03

5 Answers5

66

It's commonly used for Set-Cookie:. Many servers set more than one cookie.

Of course, you can always set them all in a single header.

Actually, I think you cannot set multiple cookies in one header. So that's a necessary use-case.

The Cookie spec (RFC 2109) does claim that you can combine multiple cookies in one header the same way other headers can be combined (comma-separated), but it also points out that non-conforming syntaxes (like the Expires parameter, which has ,s in its value) are still common and must be dealt with by implementations.

So, if you use Expires params in your Set-Cookie headers and you don't want all your cookies to expire at the same time, you probably need to use multiple headers.

Update: Evolution of the Cookie spec

RFC 2109 has been obsoleted by RFC 2965 that in turn got obsoleted by RFC 6265, which is stricter on the issue:

Origin servers SHOULD NOT fold multiple Set-Cookie header fields into a single header field. The usual mechanism for folding HTTP headers fields (i.e., as defined in [RFC2616]) might change the semantics of the Set-Cookie header field because the %x2C (",") character is used by Set-Cookie in a way that conflicts with such folding.

Side note

RFC 6265 uses the verb "folding" when it refers to combining multiple header fields into one, which is ambiguous in the context of the HTTP/1 specs (both by RFC2616, and its successor, RFC 7230) where:

  • "folding" consistently refers to line folding, and

  • the verb "combine" is used to describe merging same headers.

Combining header fields:

  • See RFC 2616, Section 4.2, Message Headers (quoted in the question), but searching for the for the word "combine" will bring up special cases.

  • The above item obsoleted by RFC 7230, Section 3.2.2, Field Order:

    A recipient MAY combine multiple header fields with the same field name into one field-name: field-value pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, 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; a proxy MUST NOT change the order of these field values when forwarding a message.

    Note: In practice, the "Set-Cookie" header field (RFC6265) often appears multiple times in a response message and does not use the list syntax, violating the above requirements on multiple header fields with the same name. Since it cannot be combined into a single field-value, recipients ought to handle Set-Cookie as a special case while processing header fields. (See Appendix A.2.3 of [Kri2001] for details.)

Line folding:

  • From RFC 2616, Section 2.2, Basic Rules:

    HTTP/1.1 header field values can be folded onto multiple lines if the continuation line begins with a space or horizontal tab. All linear white space, including folding, has the same semantics as SP. A recipient MAY replace any linear white space with a single SP before interpreting the field value or forwarding the message downstream.

  • The above section obsoleted by RFC 7230, Section 3.2.4, Field Parsing:

    Historically, HTTP header field values could be extended over multiple lines by preceding each extra line with at least one space or horizontal tab (obs-fold). This specification deprecates such line folding except within the message/http media type (Section 8.3.1). A sender MUST NOT generate a message that includes line folding (i.e., that has any field-value that contains a match to the obs-fold rule) unless the message is intended for packaging within the message/http media type.

    A server that receives an obs-fold in a request message that is not within a message/http container MUST either reject the message by sending a 400 (Bad Request), preferably with a representation explaining that obsolete line folding is unacceptable, or replace each received obs-fold with one or more SP octets prior to interpreting the field value or forwarding the message downstream.

    A proxy or gateway that receives an obs-fold in a response message that is not within a message/http container MUST either discard the message and replace it with a 502 (Bad Gateway) response, preferably with a representation explaining that unacceptable line folding was received, or replace each received obs-fold with one or more SP octets prior to interpreting the field value or forwarding the message downstream.

    A user agent that receives an obs-fold in a response message that is not within a message/http container MUST replace each received obs-fold with one or more SP octets prior to interpreting the field value.

Community
  • 1
  • 1
sligocki
  • 6,246
  • 5
  • 38
  • 47
  • You can easily set them in one header: Set-Cookie: hello=world; conception=proofed – BronzeByte Feb 15 '12 at 11:50
  • 3
    Ah, but can you set cookies with different expirations in the same Header? Say, can you convert this into one header? Set-Cookie: name1=value1; Expires=Wed, 22 Feb 2012 17:45:00 GMT Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14 GMT – sligocki Feb 22 '12 at 20:45
  • That would save a cookie in the browser called Expires and be overriden by the second..., I have built a server side session back-end in the meanwhile, 100% secure, super easy and saving of Java objects possible – BronzeByte Feb 24 '12 at 16:20
  • 4
    No, Expires has special meaning, just like Path, Secure, Domain, etc. (see http://www.ietf.org/rfc/rfc2109.txt). For example, looking at the HTTP headers for this page, I see: "Set-Cookie:usr=t=[redacted]; domain=.stackoverflow.com; expires=Fri, 12-Oct-2012 23:27:03 GMT; path=/; HttpOnly". I think all of these qualifiers (domain, expires, path and HttpOnly) must apply to all cookies set in this header. – sligocki Apr 12 '12 at 23:30
16

Since duplicate headers can cause issues with various web-servers and APIs (regardless of what the spec says), I doubt there is any general purpose use case where this is best practice. That's not to say someone somewhere isn't doing it, of course.

heisenberg
  • 9,665
  • 1
  • 30
  • 38
  • content security policy is meant to handle multiple headers. See https://twitter.com/mikewest/status/841892857736765443 to where this causes a problem. – oreoshake Apr 12 '17 at 19:51
  • 7
    Some headers are intended to be duplicated. The quantity and prevalence of these headers (e.g., `Link`) has increased since this answer was originally posted, but even then, it was common to send multiple `Set-Cookie` headers. – Zenexer Nov 26 '18 at 07:58
15

As you're looking for use-cases, maybe Accept would be a valid one.

  • Accept: application/json
  • Accept: application/xml
Andre Pena
  • 56,650
  • 48
  • 196
  • 243
11

It's only allowed for headers using a very specific format, see RFC 2616, Section 4.2.

Julian Reschke
  • 40,156
  • 8
  • 95
  • 98
  • He stated pretty clearly in the question that he realizes its allowed, that's not what he's asking. – heisenberg Jul 14 '10 at 13:13
  • 12
    That link is very helpful though. Particularly the part that headers that appear more than once, must also be able to be represented as a single header with comma-separated values. – nategood Sep 15 '12 at 15:16
1

Old thread, but I was looking into this same issue. Anyway, the Accept and Accept-Encoding headers are typical examples that uses multiple values, comma separated. Even if these are request specific header, the specs do not differentiate between request and response at this level. Check the one from this page. What the spec says is that if you have commas as character in the value of the header, you cannot use multiple headers of the same name, unless you disambiguate the use of the comma.

massiAng
  • 11
  • 1