skip to content

In SOAP, what must a node do with a mustUnderstand header block targeted at it that it does not understand, and why?

level: middleimportance: should knowfreq 22%

answer

  1. an extension that cannot be skipped
  2. only blocks aimed at this node
  3. decided before any Body work
  4. one fault, no further processing
  5. NotUnderstood names the culprit

basics

~20 s

It must not process the message and must generate a MustUnderstand fault instead. The flag marks an extension that changes what the message means, so a node that silently skipped it could act on the wrong semantics.

solid answer

~50 s

`mustUnderstand` applies only to header blocks **targeted** at the node, through `actor` in SOAP 1.1 or `role` in SOAP 1.2. For each such block marked mandatory, the node must either process it as its specification says or not process the message at all. SOAP 1.2 fixes the order: the node determines its roles, identifies every mandatory block targeted at it, and if any is not understood generates a single fault with Code `env:MustUnderstand` and does nothing further: no Body processing, and no Body-related faults from that step. It SHOULD add `NotUnderstood` header blocks naming the failing blocks. The reason is safe evolution: a mandatory block is presumed to modify the meaning of other blocks or the Body, so it must never be ignored silently. SOAP 1.1 writes the flag as `"1"`/`"0"`; SOAP 1.2 types it `xs:boolean`, with `"true"` canonical.

code

xml · 14 lines
xml
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
  <env:Header>
    <env:NotUnderstood qname="loy:PointsRedemption"
        xmlns:loy="http://example.org/loyalty"/>
  </env:Header>
  <env:Body>
    <env:Fault>
      <env:Code><env:Value>env:MustUnderstand</env:Value></env:Code>
      <env:Reason>
        <env:Text xml:lang="en">Mandatory header block not understood</env:Text>
      </env:Reason>
    </env:Fault>
  </env:Body>
</env:Envelope>

go deeper

for a junior

Recall that mustUnderstand marks a header block as mandatory for the node it targets, and that a node unable to honour it answers with a MustUnderstand fault.

for a middle

Explain the SOAP 1.2 order: roles first, then mandatory targeted blocks, then one MustUnderstand fault before any Body work, plus NotUnderstood and the 1.1 versus 1.2 attribute values.

for a senior

Show when you would mark your own header blocks mandatory: only where ignoring them changes the outcome, knowing that every receiver without support will refuse the whole message.

for a principal

Weigh mandatory header blocks as an evolution tool: they make a new extension fail closed across a partner estate, protecting meaning at the price of coordinated upgrades.

## The problem the flag solves SOAP is extended through **header blocks**: namespace-qualified children of the `Header` that add a transaction context, a security token, a routing instruction or anything else, without changing the core protocol. Most extensions can be ignored safely by a node that does not know them. Some cannot: if a header says "apply this request inside transaction 5" and a node executes the Body without knowing transactions exist, it has done the wrong thing and nobody knows. The **`mustUnderstand`** attribute marks those blocks. SOAP 1.2 calls such a block **mandatory**, and both versions say it is presumed to modify the meaning of other parts of the message, so that change is never silently ignored. A block is **understood** when the node's software was written to implement the semantics defined for that block's fully qualified element name. Recognising the XML is not enough. ## The rule in both versions | | SOAP 1.1 | SOAP 1.2 | |---|---|---| | Targeting attribute | `actor` | `role` | | Values | `"1"` mandatory, `"0"` optional | `xs:boolean`: `"true"` canonical, any valid lexical form accepted | | Attribute absent | same as `"0"` | same as `"false"` | | What the node must do | obey the semantics, or fail processing the message | process the block, or not process the message and fault | | Fault code | `MustUnderstand` | `env:MustUnderstand` | | Naming the failed block | no structure defined | `NotUnderstood` header block with a `qname` attribute | ## The order SOAP 1.2 prescribes SOAP 1.2 Part 1 lays the processing out as steps whose outcome must be equivalent to doing them separately and in order: 1. Determine the set of roles the node acts in. 2. Identify all header blocks targeted at the node that are mandatory. 3. If one or more of them is not understood, generate **a single** fault with Code `env:MustUnderstand`. No further processing may be done, and faults about the Body MUST NOT be generated in this step. 4. Otherwise, process the mandatory blocks targeted at the node and, at the ultimate receiver, the Body. Non-mandatory targeted blocks MAY also be processed. 5. An intermediary then relays the message if the exchange requires it. The check comes before the Body on purpose: the mandatory block may change what the Body means, so doing the Body's work first could cause side effects under the wrong semantics. SOAP 1.1 says the same in fewer words: identify the parts meant for this node, verify the mandatory ones are supported, and if not, discard the message. ## Reporting the failure - SOAP 1.2 says the fault SHOULD include one **`NotUnderstood`** header block per failing block, each with a `qname` attribute giving that block's qualified name. The node MAY report any one or more of the failing blocks; listing all of them is not required. - `NotUnderstood` sits in the **Header** of the fault message, not in `Detail`. - SOAP 1.1 defines the `MustUnderstand` fault code but gives no structure for naming the block, and it states that error information about header entries MUST be carried in header entries, never in `detail`. - SOAP 1.2 forbids generating more than one fault for a message, and SOAP 1.1 allows at most one `Fault` in a Body. ## What the flag does not mean - It does **not** oblige every node on the path to understand the block. Only the node the block targets is bound. - It is **not** a routing-error detector. SOAP 1.2 says explicitly that no fault is required for a mandatory block aimed at a role the node does not play: an ultimate receiver that finds a mandatory block meant for an intermediary that failed to remove it is not in error. An extension may define its own `env:Sender` fault for blocks that survived too far. - It has **no effect on Body children**. A SOAP 1.2 receiver MUST ignore `mustUnderstand` on a Body child or on any descendant of a header block. The Body needs no flag: SOAP 1.1 describes a body entry as equivalent to a header entry for the default actor with `mustUnderstand="1"`. - It does **not** stop a node from processing optional blocks; a non-mandatory block targeted at the node may be processed or ignored. ## Using it as a designer Mark a header block mandatory only when ignoring it would change the outcome: a transaction context, a security requirement, a "quote only, do not book" instruction. The cost is real. Every receiver without support for that block refuses the whole message, so a new mandatory header forces every consumer on that path to upgrade before it can talk to you. An optional block lets old receivers carry on unaware, which is exactly right for hints and exactly wrong for anything that alters meaning.

  • Is it a SOAP 1.2 error when the ultimate receiver finds a mandatory header block aimed at a role it does not play?
    No. SOAP 1.2 says `mustUnderstand` is not a mechanism for detecting routing or targeting errors and requires no fault for a block not targeted at the current node, even a mandatory one that survived an intermediary's mistake. An extension can define its own `env:Sender` fault for blocks found past their intended point.
  • Does mustUnderstand force a node to process every header block it receives?
    No. It binds only the node a block is targeted at, and only for blocks marked mandatory. Non-mandatory blocks targeted at the node MAY be processed or ignored, and blocks aimed at other roles are not the node's to process at all.
  • Why must the MustUnderstand check run before the Body is processed?
    Because a mandatory block is presumed to change what the Body means, such as a transaction or a quote-only instruction. SOAP 1.2 requires that once the MustUnderstand fault is generated no further processing is done, and that this step produces no Body-related faults, so no side effect happens under the wrong semantics.

A clause in a contract initialled as a material term: a clerk who does not know what that clause obliges them to do may not sign the rest and ignore it. They must refuse the whole contract and say which clause stopped them.

saying these in an interview costs you the question

  • mustUnderstand means every node on the path must understand the block.
  • A node may skip a mandatory block it does not support and carry on.
  • Putting mustUnderstand on a Body child makes that payload mandatory.
  • mustUnderstand exists to catch header blocks routed to the wrong node.
  • SOAP 1.2 receivers accept only the literal value true for mustUnderstand.
  • The node should report each unknown mandatory block in a separate fault.