How does a SOAP service over HTTP report an error compared with a REST API, and what can generic HTTP infrastructure learn from each?
answer
- where the error's meaning lives
- a Fault inside the Body
- SOAP 1.1 says 500 for all
- SOAP 1.2: Sender 400, rest 500
- status class plus problem details
basics
~20 sSOAP puts the error in a Fault element inside the envelope, under a coarse HTTP status: 500 in SOAP 1.1, 400 or 500 in SOAP 1.2. REST makes the status code itself the main signal and adds details in the body.
solid answer
~50 sIn SOAP an error is a message: the response Body holds a single `Fault` whose code says whose fault it is - `Client` or `Server` in SOAP 1.1, `Sender` or `Receiver` in SOAP 1.2 - and whose detail carries the application's error, usually declared in the WSDL. The HTTP binding only maps that to a coarse status: SOAP 1.1 MUST answer `500` for any SOAP error, while SOAP 1.2's binding sends `400` for a `Sender` fault and `500` for the others. A REST API puts the meaning in the status itself - `404`, `409`, `503` - which every HTTP client, proxy, gateway and dashboard understands at least by class, and adds a body such as RFC 9457 problem details for specifics. So infrastructure can tell "not found" from "overloaded" in a REST API without parsing anything; with SOAP it mostly sees 500s and must open the XML.
code
http · 18 linesHTTP/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">Tax period is closed</env:Text>
</env:Reason>
<env:Detail>
<f:PeriodClosed xmlns:f="http://filing.example.org/faults">2025-Q4</f:PeriodClosed>
</env:Detail>
</env:Fault>
</env:Body>
</env:Envelope>go deeper
Remember that a SOAP error is a Fault element inside the response Body, while a REST error is primarily its HTTP status code.
Explain both mappings: SOAP 1.1 sends 500 for any fault; SOAP 1.2 sends 400 for Sender and 500 for the others. Contrast with REST's status classes plus a body.
Talk about the operational cost: SOAP business faults inflate 5xx alerts, hide from generic retry logic and break behind body-rewriting proxies.
Weigh typed, transport-independent faults against infrastructure visibility, and say how an estate standardises error reporting when both styles coexist.
## Two places an error can live Every HTTP API has two channels for reporting failure: the **status line** that every HTTP component reads, and the **body** that only the application understands. SOAP and REST put the error's meaning in different channels, and that choice decides what monitoring, gateways and client libraries can do without custom code. ## How SOAP reports an error A SOAP error is itself a SOAP message. The response `Body` contains one `Fault` element - SOAP 1.2 says a message carrying error information MUST have a single `Fault` as the only child of the Body, and SOAP 1.1 says a `Fault` MUST NOT appear more than once. - In **SOAP 1.1** the Fault has `faultcode`, `faultstring`, an optional `faultactor` and `detail`. The standard codes include `Client` (the request was wrong) and `Server` (processing failed). - In **SOAP 1.2** it has `Code` (a `Value`, optionally refined by nested `Subcode`s), `Reason` with one or more language-tagged `Text` elements, optional `Node` and `Role`, and `Detail`. `Client` and `Server` were renamed `Sender` and `Receiver`. - The **application error** - "tax period closed", "card declined" - goes into `detail` / `Detail`, and a WSDL can declare it as a named fault message so generated client code raises a typed exception. The HTTP binding then maps the fault to a status code: | Situation | SOAP 1.1 over HTTP | SOAP 1.2 over HTTP | REST over HTTP | |---|---|---|---| | Caller sent bad data | `500` + `Client` fault | `400` + `Sender` fault | `400` or `422` + error body | | Item does not exist | `500` + fault, meaning in `detail` | `400` + `Sender` fault, if the service blames the request | `404` | | Bug in the service | `500` + `Server` fault | `500` + `Receiver` fault | `500` | | Temporarily overloaded | `500` + `Server` fault | `500` + `Receiver` fault | `503`, often with `Retry-After` | The SOAP 1.1 Note states that on "a SOAP error while processing the request, the SOAP HTTP server MUST issue an HTTP 500", and the WS-I Basic Profile repeats it. SOAP 1.2 Part 2's fault-to-status table maps `env:Sender` to `400` and `VersionMismatch`, `MustUnderstand`, `Receiver` and `DataEncodingUnknown` to `500`. ## How REST reports an error A REST API treats the **status code as the primary result**. RFC 9110 requires every client to understand at least the class of any status code - an unknown `471` is handled as a `400` - so even a generic library knows whether to blame the request (4xx) or the server (5xx). The specifics go in the body, ideally in a shared shape: RFC 9457 problem details (which replaced RFC 7807) define the `application/problem+json` type with `type`, `title`, `status`, `detail` and `instance` members. ## What generic HTTP infrastructure learns - **Gateways and dashboards** can chart 4xx against 5xx per route for a REST API. For SOAP 1.1, a declined card and a crashed database both appear as `500` on the same endpoint URL. - **Alerting** tuned to 5xx rates fires on SOAP business faults, so teams end up parsing XML in the gateway or accepting noisy alerts. - **Retry logic** in generic clients keys on status: `503` with `Retry-After` tells it to wait, `400` tells it not to retry. A SOAP fault's retry-worthiness is not signalled at the HTTP layer at all. - **Body-rewriting intermediaries** are a SOAP hazard: SOAP 1.2 Part 2 warns that infrastructure configured to replace the bodies of 4xx and 5xx responses destroys the Fault, and says SOAP over HTTP "cannot be used in such configurations" if that behaviour cannot be disabled. ## What SOAP's approach buys 1. **Transport independence.** The same Fault travels over a message queue binding, where no HTTP status exists. 2. **A typed contract.** Faults declared in a WSDL become typed errors in every generated client. 3. **One structure everywhere.** Every SOAP service shares the Fault shape; REST APIs agree on a body format only if they adopt a convention such as problem details. ## How to frame it in an interview Say where each style puts the meaning, give the SOAP 1.1 and SOAP 1.2 status mappings correctly, and name the operational consequence: SOAP errors are richer for the calling code and nearly invisible to generic HTTP tooling, while REST errors are visible to everything but only as structured as the API's own conventions make them.
- Does a SOAP 1.2 Sender fault always reach the client with status 400?Over the SOAP 1.2 HTTP binding, Part 2's mapping table assigns `400` to `env:Sender` and `500` to the other fault codes. Over another binding, such as a message queue, there is no HTTP status at all, and the Fault inside the envelope is the only signal. Which code a service picks for a business error is its own decision, so the status says only who is blamed, not what went wrong.
- A gateway in front of a SOAP service replaces every 500 response body with a friendly HTML error page. What breaks?Every SOAP fault. The Fault lives in the response body, so the client receives HTML instead of an envelope and cannot raise the typed error the WSDL promised. SOAP 1.2 Part 2 warns about exactly this and recommends disabling such rewriting for SOAP endpoints; if it cannot be disabled, SOAP over HTTP cannot be used there.
saying these in an interview costs you the question
- SOAP faults are always sent with HTTP 500, whatever the SOAP version.
- A SOAP fault is returned with HTTP 200 because the exchange itself succeeded.
- SOAP 1.2 still uses the fault codes Client and Server.
- Gateways can classify SOAP errors by status code just as they do REST errors.
- REST APIs must return RFC 9457 problem details for every error.