IBM Support

WSWS3173E: Error: Did not understand "MustUnderstand"
header(s) occurs when invoking a Web service

Troubleshooting


Problem

One of the following errors occur when invoking a Web service with WS-Security: WSWS3173E: Error: Did not understand "MustUnderstand" header(s):{[http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd]}Security -or- org.apache.axis2.AxisFault: Must Understand check failed for headers: {[http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd]}Security [
]

Diagnosing The Problem

A SOAP Security header looks like this:

<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sece…;

Sample of a full SOAP message that includes a Security header

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">


<soapenv:Header>                                                      
  <wss:Security soapenv:mustUnderstand="1" xmlns:wss="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
     <wss:UsernameToken>                                              
        <wss:Username>username</wss:Username>                        
        <wss:Password>password</wss:Password>                        
     </wss:UsernameToken>                                            
   </wss:Security>                                                    
   </soapenv:Header>                                                  
   <soapenv:Body>                                                    
   <se:Echo xmlns:se="http://webservice.net/Service" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance">                      
      <se:value xsi:nil="true"/>                                      
   </se:Echo>                                                        
   </soapenv:Body>                                                    
</soapenv:Envelope>

A must understand error can originate from a client or provider application. One of the following has happened:

  • The client sent a Security header in a SOAP request and the provider was not expecting one.
  • The provider sent a Security header in a SOAP response and the client was not expecting one.

The JAX-WS and JAX-RPC runtimes emit different error messages for must understand errors:
The JAX-WS and JAX-RPC runtimes can produce this error for different reasons:
  • JAX-WS
  • When a WebSphere full profile JAX-WS application emits this error, it is caused by one of the following:
    • No inbound WS-Security constraints applied to the application
    • The policy was not loaded properly
    • The inbound bindings were not loaded properly
  • JAX-RPC
    • When a WebSphere JAX-RPC application emits this error, it can only caused by no inbound WS-Security constraints being applied to the application.

Note: It is possible for you to be running a JAX-RPC client and receive a org.apache.axis2.AxisFault: Must Understand check failed for headers error. It is also possible for you to be running a JAX-WS client and receive a WSWS3173E: Error: Did not understand "MustUnderstand" header(s) error. What this means is that your JAX-RPC client is communicating with a JAX-WS provider (or vice versa) and the provider has emitted the error.

Resolving The Problem

See the section that corresponds to the runtime that you are using:

JAX-WS

Finding the origination of the error
When you see a must understand error on a client application, you need to determine if the error was received in a SOAP response or if the error originated from the client itself. To see if the error was received in a SOAP response, do the following steps with a WS-Security trace; information on how to obtain a WS-Security trace can be found on MustGather: Web Services Security (WS-Security) problems with WebSphere Application Server:

  1. Find the Must Understand check failed for headers error in the trace.
  2. Find the inbound SOAP message by searching backwards for "Inbound HTTP" on the same thread (or WSWS3570I if your messages are not in English).
  3. Do one of the following:
    • If your client and provider are NOT running in the same JVM:
      • If the Must Understand check failed for headers error is in the inbound SOAP message, then the error originated on the service provider. If not, it originated on the client.
    • If your client and provider are running in the same JVM:
      • If you find Inbound HTTP SOAP Request when you search backwards for Inbound HTTP from the first WSWS3173E error in the trace, then the error originated on the provider. Otherwise, it originated on the client.
  4. Perform the rest of your problem determination on the point of origin (either in a client or provider trace)

Checking if the error is because there is no policy or there was an error loading the policy (or binding)
If there is no inbound policy attached, you will see an entry like the following in a WS-Security trace:
WSSecurityCon 3 No PolicyType Binding

If you don't see that, search backwards in the trace from the error point for "not loaded properly". If you see this, there was an error loading the policy or bindings for the application.

Checking if Security constraints are applied for generating a request on a client
When you are expecting a SOAP message to contain a Security header, but it does not, you will most likely see entries like the following in a WS-Security trace. This trace entry means that there is no outbound policy set attached to the application.


A trace snip is from a client on the request message:
WSSecurityGen > invoke(MessageContext msgContext) Entry
Axis2Util 3 getAxisService().isClientSide() = true
WSSecurityGen 3 isServerSide=false
WSSecurityGen 3 Get policy for application
WSSecurityGen 3 No PolicyType Binding
WSSecurityGen 3 Application Generator Policy=null
WSSecurityGen < invoke(MessageContext msgContext) Exit

Checking if Security constraints are applied for consuming a response on a client
This trace snip is from a client on the response message:
WSSecurityCon > invoke(MessageContext msgContext) Entry
Axis2Util 3 getAxisService().isClientSide() = true
WSSecurityCon 3 isServerSide == false
WSSecurityCon 3 No PolicyType Binding
WSSecurityCon 3 Cannot find WSSAPI_CONFIG_KEY_CONSUMER on MessageContext Options. Look in WSS_PROPERTYMAP property map.
TokenHolder > getPropertyMapFromInboundMessageContext(MessageContext messageContext Entry
TokenHolder 3 Looking for WSS_PROPERTYMAP in the inbound message context
TokenHolder < getPropertyMapFromInboundMessageContext(MessageContext messageContext) returns = null Exit
WSSecurityCon 3 WSS_PROPERTYMAP map not found.
WSSecurityCon 3 WSSAPI consumer bindings not found. Response message will not be processed by web services security.

The WS-Security configuration of the Web service client and Web service provider must match. After completing these steps, you will know if your client is sending a Security header that the provider is not expecting or the other way around.

Do one of the following:
  • If the binding was not loaded properly, fix the error that caused the binding to not load properly.
  • Attach the same policy set to both the client and provider application:
  • Remove outbound WS-Security constraints from the application that is sending the Security header.
  • Add inbound WS-Security constraints to the application that is not expecting the Security header.

JAX-RPC

Identifying the error
When a WebSphere JAX-RPC application emits a must understand error, it can only caused by no inbound WS-Security constraints being applied to the application. The WS-Security configuration of the Web service client and Web service provider must match.

You will see a stack trace similar to this in a web services provider trace when a provider emits a must understand error:
[17/05/06 11:58:29:278 BST] 00000046 UserException E WSWS3228E: Error: Exception: WebServicesFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/]}MustUnderstand faultString: WSWS3173E: Error: Did not understand "MustUnderstand" header(s):{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sece…}Security
faultActor: null
faultDetail:

WSWS3173E: Error: Did not understand "MustUnderstand" header(s):{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security
at com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCSOAPHandler.checkSOAPSemantics(JAXRPCSOAPHandler.java:355)
at com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCSOAPHandler.invokeServerRequestHandler(JAXRPCSOAPHandler.java:183)
at com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCHandler$1.invoke(JAXRPCHandler.java:379)
at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:205)
at com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCHandler.invoke(JAXRPCHandler.java:151)
at com.ibm.ws.webservices.engine.handlers.WrappedHandler.invoke(WrappedHandler.java:64)
....

When a client emits a must understand error, this class will be in the stack instead of invokeServerRequestHandler:
com.ibm.ws.webservices.engine.handlers.jaxrpc.JAXRPCSOAPHandler.invokeClientResponseHandler


Setting up the trace
To setup a WS-Security trace, you can use the information on MustGather: Web Services Security (WS-Security) problems with WebSphere Application Server. Update the trace string to add this entry:
com.ibm.ws.webservices.*=all

If you do not add this entry, if the must understand error is emitted by a JAX-RPC client, it will not show up in the trace.


Finding the origination of the error
When you see the must understand error in a JAX-RPC client application, you need to determine if the error was received in a SOAP response or if the error originated from the client itself. To see if the error was received in a SOAP response, do the following steps with a WS-Security trace (as described above):

  1. Find the WSWS3173E: Error: Did not understand "MustUnderstand" header error in the trace.
  2. Find the inbound SOAP message by searching backwards for "Inbound HTTP" on the same thread (or WSWS3570I if your messages are not in English).
  3. Do one of the following:
    • If your client and provider are NOT running in the same JVM:
      • If the WSWS3173E: Error: Did not understand "MustUnderstand" header error is in the inbound SOAP message, then the error originated on the service provider. If not, it originated on the client.
    • If your client and provider are running in the same JVM:
      • If you find Inbound HTTP SOAP Request when you search backwards for Inbound HTTP from the first WSWS3173E error in the trace, then the error originated on the provider. Otherwise, it originated on the client.
  4. Perform the rest of your problem determination on the point of origin (either in a client or provider trace)
    • Confirm that there are no WS-Security constraints by searching backwards in the origin trace from WSWS3173E for No WSSConsumerConfig or ReceiverConfig found on the same thread.


Checking a JAX-RPC application's WS-Security configuration
To check if the Web service provider has the proper WS-Security configuration, examine the ibm-webservices-ext.xmi and ibm-webservices-bnd.xmi files. Client applications use ibm-webservicesclient-ext.xmi and ibm-webservicesclient-bnd.xmi.

If WS-Security is configured, you will see something similar to this. This example is configured to use basic authentication with a Username token:

  • ibm-webservices-ext.xmi
  • <?xml version="1.0" encoding="UTF-8"?>
    <com.ibm.etools.webservice.wsext:WsExtension xmi:version="2.0" xmlns:xmi="<font>http://www.omg.org/XMI&quot; xmlns:com.ibm.etools.webservice.wsext="http://www.ibm.com/websphere/appserver/schemas/5.0.2/wsext.xmi&quot; xmi:id="WsExtension_1143217797354">
    <wsDescExt xmi:id="WsDescExt_1147104022147" wsDescNameLink="NameOfWebSvcService">
    <pcBinding xmi:id="PcBinding_1147104022147" pcNameLink="NameOfWebSvc">
    <serverServiceConfig xmi:id="ServerServiceConfig_1147345532307">
    <securityRequestConsumerServiceConfig xmi:id="SecurityRequestConsumerServiceConfig_1147345532307">
    <caller xmi:id="Caller_1148060100320" name="req_principalUserpart" part="" uri="" localName="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-…;
    <requiredSecurityToken xmi:id="RequiredSecurityToken_1148060100320" name="req_principalUsertok" uri="" localName="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-…;
    </securityRequestConsumerServiceConfig>
    </serverServiceConfig>
    </pcBinding>
    </wsDescExt>
    </com.ibm.etools.webservice.wsext:WsExtension>

  • ibm-webservices-bnd.xmi
  • <?xml version="1.0" encoding="UTF-8"?>
    <com.ibm.etools.webservice.wsbnd:WSBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI&quot; xmlns:com.ibm.etools.webservice.wsbnd="http://www.ibm.com/websphere/appserver/schemas/5.0.2/wsbnd.xmi&quot; xmi:id="WSBinding_1143217760366">
    <wsdescBindings xmi:id="WSDescBinding_1147104021606" wsDescNameLink="NameOfWebSvcService">
    <pcBindings xmi:id="PCBinding_1147104021606" pcNameLink="NameOfWebSvc">
    <securityRequestConsumerBindingConfig>
    <tokenConsumer classname="com.ibm.wsspi.wssecurity.token.UsernameTokenConsumer" name="con_untcon">
    <valueType localName="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-…; uri="" name="Username Token"/>
    <jAASConfig configName="system.wssecurity.UsernameToken"/>
    <partReference part="req_principalUsertok"/>
    </tokenConsumer>
    </securityRequestConsumerBindingConfig>
    </pcBindings>
    </wsdescBindings>
    </com.ibm.etools.webservice.wsbnd:WSBinding>


Resolving the problem
If the files do not contain any WS-Security information, then two options are available to resolve the problem:
  1. If WS-Security is not required, modify the client code so that security information is not passed to the Web service.
  2. If WS-Security is required, configure the Web service provider application to use the same type of authentication as the Web service client.

The only supported way to change the WS-Security configuration for a JAX-RPC application is with an assembly tool, such as Rational Application Developer. The WebSphere Version 6 Web Services Handbook Development and Deployment Redbook contains instructions on how to setup WS-Security for clients and providers. See:

  • Chapter 21. Securing Web Services
    • Development of WS-Security -> Authentication
      • Configuring the client for a security token
      • Configuring the server for security token

Using SCA in Business Process Manager (BPM)

Identifying the error
A web service call of a Service Component Architecture (SCA) import web service binding might lead to a "AxisFault: Must Understand check failed" exception when a SOAP request needs to include some additional SOAP header information.
If a web service binding is used as an SCA import module to call an external web service, the following exception might occur during the invocation of this SCA module in the SystemOut.log file:

Exception:javax.xml.ws.WebServiceException SourceId:com.ibm.ws.sca.internal.jaxws.handler.
JaxWsPortHandler.processMessage ProbeId:01
javax.xml.ws.WebServiceException: org.apache.axis2.AxisFault: Must Understand check failed for header
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sece… Security
at org.apache.axis2.jaxws.ExceptionFactory.createWebServiceException(ExceptionFactory.java:175)
at org.apache.axis2.jaxws.ExceptionFactory.makeWebServiceException
...
Caused by: org.apache.axis2.AxisFault: Must Understand check failed for header
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sece… : Security
at org.apache.axis2.engine.AxisEngine.checkMustUnderstand(AxisEngine.java:115)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:179)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:363)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:416)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
at org.apache.axis2.jaxws.core.controller.impl.AxisInvocationController.execute(AxisInvocationController.java:581)
... 137 more

Cause
The cause of the problem is a policy mismatch between the web service client and the web service provider. This error is exclusively caused by an application sending a SOAP Security header, but the receiver not expecting it. One of the following has happened:

  • The client sent a SOAP Security header in a request that the provider did not expect.
  • The provider sent a SOAP Security header in a response that the client did not expect.

In IBM Business Process Manager, WebSphere Process Server, or WebSphere Enterprise Service Bus, SOAP Security header information is not processed by default. If a web service call requires some additional SOAP header information, the web service call needs to be modified properly to match the web service partner expectation.

Diagnosis
When you see this error on a client application, you need to determine if the error was received in a SOAP response or if the error originated from the client by processing a 'good' SOAP response. To do this, expand the JAX-WS section above and perform the steps under Finding the origination of the error.

Resolving the problem

You can fix this error in one of the following two ways:


  1. Remove outbound WS-Security constraints from the application that is sending the Security header.
  2. If your client is sending a Security header in a request to your BPM provider that is not expecting one:
  • See the Resolving the problem section for the JAX-RPC or JAX-WS sections above (depending on the application type). Use the information to remove inbound WS-Security constraints.
  • If your BPM provider is sending a Security header in a response to a WebSphere client that is not expecting one:
  1. Add inbound WS-Security constraints to the application that is not expecting the Security header
  2. If your BPM provider is sending a Security header in a response to a WebSphere client that is not expecting one:
  • See the Resolving the problem section for the JAX-RPC or JAX-WS sections above (depending on the application type). Use the information to add inbound WS-Security constraints.
  • If your client is sending a Security header in a request to your BPM provider that is not expecting one:
  • In IBM Integration Designer and WebSphere Integration Developer, it is possible to write your own SOAPDataHandler to add the missing header information. This specific SOAPDataHandler needs to be configured in the Assembly Diagram of the Web Service SCA Import module. In IBM Integration Designer and WebSphere Integration Developer, open the Properties > JAX-WS Handlers section and add the SOAPDataHandler to the JAX-WS Handlers.

    A sample SOAPDataHandler, which includes this header information, is available in the following example:

    package com.ibm.samples;
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.Set;
    import javax.xml.namespace.QName;
    import javax.xml.soap.SOAPElement;
    import javax.xml.soap.SOAPEnvelope;
    import javax.xml.soap.SOAPException;
    import javax.xml.soap.SOAPFactory;
    import javax.xml.soap.SOAPHeader;
    import javax.xml.ws.handler.MessageContext;
    import javax.xml.ws.handler.soap.SOAPHandler;
    import javax.xml.ws.handler.soap.SOAPMessageContext;

    public class mySoapHandler implements SOAPHandler<SOAPMessageContext> {
      private static final String AUTH_NS = "http://docs.oasis-open.org/
        wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
        private static final String AUTH_PREFIX = "wss";
      public Set<QName> getHeaders() {
        try {
          SOAPFactory sf = SOAPFactory.newInstance();
          SOAPElement se = sf.createElement("Security", AUTH_PREFIX, AUTH_NS);
          Set<QName> headers = new HashSet<QName>();
          headers.add(se.getElementQName());
          return headers;
        } catch (SOAPException e) {
          e.printStackTrace();
          return Collections.emptySet();
        }
      }
      public boolean handleMessage(SOAPMessageContext smc) {
        boolean direction = ((Boolean) smc.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
        try {
          String userName = "username";
          String password = "password";
          SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
          SOAPFactory soapFactory = SOAPFactory.newInstance();

          // WSSecurity <Security> header
          SOAPElement wsSecHeaderElm = soapFactory.createElement("Security", AUTH_PREFIX, AUTH_NS);

          //create username and password element
          SOAPElement userNameElm = soapFactory.createElement("Username", AUTH_PREFIX, AUTH_NS);
          userNameElm.addTextNode(userName);

          SOAPElement passwdElm = soapFactory.createElement("Password", AUTH_PREFIX, AUTH_NS);
          passwdElm.addTextNode(password);

          //create username token element
          SOAPElement userNameTokenElm = soapFactory.createElement("UsernameToken", AUTH_PREFIX, AUTH_NS);
          userNameTokenElm.addChildElement(userNameElm);
          userNameTokenElm.addChildElement(passwdElm);

          // add child elements to the root element
          wsSecHeaderElm.addChildElement(userNameTokenElm);

          // create SOAPHeader instance for SOAP envelope
          SOAPHeader sh = envelope.addHeader();

          // add SOAP element for header to SOAP header object
          sh.addChildElement(wsSecHeaderElm);
        } catch (SOAPException e) {
          e.printStackTrace();
        }
        return true;
      }
      public boolean handleFault(SOAPMessageContext smc) {
        return true;
      }
      public void close(MessageContext smc) {
      }

[{"Product":{"code":"SSEQTP","label":"WebSphere Application Server"},"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Component":"Web Services Security","Platform":[{"code":"PF002","label":"AIX"},{"code":"PF010","label":"HP-UX"},{"code":"PF016","label":"Linux"},{"code":"PF027","label":"Solaris"},{"code":"PF033","label":"Windows"},{"code":"PF035","label":"z\/OS"},{"code":"PF013","label":"Inspur K-UX"}],"Version":"9.0;8.5;8.0;7.0","Edition":"Base;Network Deployment;Single Server","Line of Business":{"code":"LOB45","label":"Automation"}},{"Product":{"code":"SSNVBF","label":"Runtimes for Java Technology"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Component":"Java SDK","Platform":[{"code":"","label":""}],"Version":"","Edition":"","Line of Business":{"code":"LOB36","label":"IBM Automation"}}]

Document Information

Modified date:
22 June 2018

UID

swg21238420