skip to content

When the same operation moves from SOAP 1.1 to SOAP 1.2 over HTTP, what changes in the HTTP request and response?

level: middleimportance: must knowfreq 30%

answer

  1. two media types, one registered later
  2. where the action URI travels
  3. a header removed, a parameter added
  4. fault status: Sender versus the rest

basics

~20 s

SOAP 1.1 sends text/xml with a mandatory SOAPAction header and returns faults with HTTP 500. SOAP 1.2 sends application/soap+xml with an optional action parameter, returns Sender faults with 400 and other faults with 500, and also permits GET.

solid answer

~40 s

SOAP 1.1's HTTP binding uses `POST`, `Content-Type: text/xml` and a `SOAPAction` request header the client MUST send: a quoted URI, where `""` means the Request-URI states the intent. SOAP 1.2's HTTP binding (Part 2, section 7) removes that header; the same URI travels as the optional `action` parameter of `application/soap+xml`, the media type RFC 3902 registers. Faults change too: SOAP 1.1 requires `500` for every fault, while SOAP 1.2's Table 20 maps `env:Sender` to `400` and the other fault codes to `500`. SOAP 1.2 also allows `GET` for safe retrievals through its SOAP Response message exchange pattern. A SOAP 1.2-only endpoint may refuse a `text/xml` request with `415` before reading it, so version mismatches often surface as HTTP errors, not business faults.

code

http · 23 lines
http
POST /quotes HTTP/1.1
Host: api.example.com
Content-Type: application/soap+xml; charset=utf-8; action="http://example.com/quotes/GetQuote"

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
  <env:Body>
    <q:GetQuote xmlns:q="http://example.com/quotes">
      <q:symbol>ZZZZ</q:symbol>
    </q:GetQuote>
  </env:Body>
</env:Envelope>

HTTP/1.1 400 Bad Request
Content-Type: application/soap+xml; charset=utf-8

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
  <env:Body>
    <env:Fault>
      <env:Code><env:Value>env:Sender</env:Value></env:Code>
      <env:Reason><env:Text xml:lang="en">Unknown symbol</env:Text></env:Reason>
    </env:Fault>
  </env:Body>
</env:Envelope>

go deeper

for a junior

Recall the two media types, text/xml for SOAP 1.1 and application/soap+xml for SOAP 1.2, and that SOAP 1.1 sends a SOAPAction header.

for a middle

Explain where the action URI moved in SOAP 1.2, the fault-to-status table with Sender as the 400 exception, and the GET retrieval through the SOAP Response pattern.

for a senior

Diagnose a version mismatch from HTTP evidence alone: a 415 before processing, a missing SOAPAction, a VersionMismatch fault, and status codes your monitoring misreads.

for a principal

Weigh exposing both SOAP versions from one service: the doubled HTTP surface, how alerting and retries must read fault codes, and when one version can be retired.

## What an HTTP binding decides A SOAP envelope is transport-neutral: the same `Envelope`, `Header` and `Body` can travel over HTTP, a message queue or mail. A **binding** is the specification that says how a message rides a particular transport. For HTTP it fixes four things: - the **HTTP method** a request uses; - the **media type** in `Content-Type`; - where the operation's **action URI** goes; - which **HTTP status** a response carries, including a response that holds a SOAP Fault. SOAP 1.1 (a W3C Note from 2000, never a Recommendation) and SOAP 1.2 (a W3C Recommendation; its HTTP binding is Part 2, section 7) answer all four differently. That is why one operation exposed in both versions produces two visibly different HTTP exchanges, and why a client built for one version can fail against the other before the Body is ever read. ## SOAP 1.1 over HTTP Section 6 of the SOAP 1.1 Note defines the binding: - **Method:** it "only defines SOAP within HTTP POST requests". - **Media type:** applications "MUST use the media type `text/xml`". - **`SOAPAction` header:** "An HTTP client MUST use this header field when issuing a SOAP HTTP Request." The value is a quoted URI naming the intent. `SOAPAction: ""` means the Request-URI expresses the intent; the header with no value at all means there is no indication. The Note adds that firewalls can filter on it. - **Faults:** on a SOAP processing error the server "MUST issue an HTTP 500" response containing the Fault, whatever the fault code. ```http POST /quotes HTTP/1.1 Host: api.example.com Content-Type: text/xml; charset="utf-8" SOAPAction: "http://example.com/quotes/GetQuote" ``` WS-I Basic Profile 1.1 later tightened this: the `SOAPAction` value MUST be a quoted string, and the profile calls it "purely a hint", because the envelope carries everything vital about the message's intent. ## SOAP 1.2 over HTTP Part 2 changes each answer: - **Media type:** `application/soap+xml`, registered by RFC 3902. - **Action:** the `SOAPAction` header is removed. The same URI travels as the optional `action` parameter of the media type. When the SOAP Action feature has a value, the sender MUST put it there, and it must be an absolute, non-empty URI. - **Methods:** `POST` and `GET`. `GET` pairs with the **SOAP Response message exchange pattern**: a safe retrieval with no request envelope, where only the response is a SOAP message. A method that is neither draws `405`. - **Faults:** Table 20 maps fault codes to statuses. | SOAP 1.2 fault code | HTTP status | |---|---| | `env:Sender` | 400 Bad Request | | `env:Receiver` | 500 Internal Server Error | | `env:MustUnderstand` | 500 | | `env:VersionMismatch` | 500 | | `env:DataEncodingUnknown` | 500 | Before any envelope is processed, the binding can also refuse at the HTTP layer (Table 18): `400` for a malformed request, `405` for a method other than POST or GET, `415` for an unsupported media type. No Fault exists at that point, because no SOAP message has been received. ## The same call, side by side | Aspect | SOAP 1.1 | SOAP 1.2 | |---|---|---| | `Content-Type` | `text/xml` | `application/soap+xml` | | Action URI | `SOAPAction` header, required | `action` parameter, optional | | Methods | `POST` | `POST`, plus `GET` for the Response pattern | | Fault status | always 500 | 400 for Sender, 500 for the rest | The envelope's namespace is the version signal inside the message; the HTTP headers and that namespace have to agree. ## What breaks when one side assumes the other version 1. **A SOAP 1.1 client against a SOAP 1.2-only endpoint** sends `text/xml`; the binding may answer `415` before SOAP processing, and a node that does process the 1.1 envelope answers with a VersionMismatch fault. 2. **A SOAP 1.2 client against a SOAP 1.1 service** sends no `SOAPAction`; a 1.1 server that relies on that header to route cannot place the call, even though the Body is fine. 3. **Monitoring that reads 4xx as caller error and 5xx as outage** misreads SOAP 1.1: a caller's invalid input still arrives as `500`. Under SOAP 1.2 the same mistake arrives as `400`. 4. **Retry logic keyed only on status code** retries SOAP 1.1 `500` responses that are really the caller's fault unless it inspects the fault code. One trap sits in the documents themselves. The SOAP 1.2 Primer's Example 11 shows an `env:Sender` fault returned with `500`. The Primer is non-normative; Part 2's Table 20, which says `400`, is the rule an implementation is measured against.

  • Why did WS-I Basic Profile 1.1 call SOAPAction 'purely a hint'?
    Because everything vital about a message's intent is in the envelope. Firewalls and dispatchers may use the header, but a receiver should be able to identify the operation from the Body's child element. The profile still requires the header in SOAP 1.1 requests, as a quoted string equal to the binding's `soapAction` or `""`.
  • When does the SOAP 1.2 HTTP binding use GET, and what does the request carry?
    With the SOAP Response message exchange pattern, for a safe retrieval. The request is an ordinary HTTP `GET` with no SOAP envelope; only the response is a SOAP message in `application/soap+xml`. Unsafe operations stay on `POST` with the Request-Response pattern.
  • A SOAP 1.2 service returns HTTP 500 with an env:Sender fault. Is it conformant?
    Not to Part 2's Table 20, which maps `env:Sender` to `400`. The Primer's own Example 11 shows that combination, but the Primer is non-normative. A client should still read the fault code rather than trust the status alone, because deployed services differ.

saying these in an interview costs you the question

  • SOAP 1.2 still requires a SOAPAction HTTP header on every request.
  • Every SOAP fault, in any version, travels with HTTP 500.
  • SOAP 1.1 and SOAP 1.2 both use the text/xml media type.
  • The HTTP status alone tells you whether the caller or the service is at fault.
  • SOAP over HTTP can only ever use POST.