SOAP Fault Message Structure

This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.

Reponses to SOAP requests can take one of two forms: success responses or error responses. For an error response, the response could contain either HTTP errors or SOAP faults. A success response is always a SOAP message. For more information, see SOAP Response Message Structure.

For an HTTP error, the probable error might include the following HTTP error code: "400 Bad request (e.g. invalid header format)."

However, after a request has succeeded at the HTTP protocol layer, it is processed by the SOAP language pipe. This does not generate HTTP-level error responses. After the language pipe starts processing a request, the only errors it can generate are SOAP faults.

When SOAP faults are generated, they are returned as HTTP 500 errors. The errors are generated in the following cases while parsing the SOAP envelope that is contained in the request:

  • SOAP envelope is not valid, such as parse error, missing elements, and so on.

  • Out of memory conditions during parsing.

  • SQL Server login failures.

  • Unsupported SOAP operation, such as stored procedure not found or unknown operation specified.

  • Other errors that are passed through and converted from execution of a stored procedure or user-defined function in the request, such as the number of parameters specified were not valid.

In the structure of a SOAP fault response, the <faultcode> and <detail> elements provide specific additional information about the error. The <faultcode> element is consistent with the SOAP 1.1 and SOAP 1.2 fault code specifications. However, the <detail> element includes a modification outside the SOAP specifications. It provides the same detailed information about SOAP faults to both SOAP 1.2 and SOAP 1.1 clients by embedding the complete SOAP 1.2 fault structure in the <detail> node of a SOAP 1.1 fault.

All SOAP faults belong into one of the following four cases:

  • Detailed SOAP fault code information provided, but no SQL Server error messages.

    When this behavior occurs, the SOAP result maps to an appropriate SOAP fault.

  • Detailed SOAP fault code provided, with more detailed SQL Server error message in the detail node.

    Some SQL Server error messages are explicitly handled and mapped to appropriate SOAP faults.

  • An 'unknown SQL error' SOAP fault code was returned, together with a more detailed SQL Server error message in the <detail> node.

    When this behavior occurs, an SQL error was raised from somewhere in the code, but there is no special mapping to a particular SOAP fault.

  • An 'unknown SQL error' SOAP fault code was returned with no SQL Server error messages.

    When this behavior occurs, an unknown result was returned somewhere and mapped to the 'unknown SQL error' SOAP fault.

Sample SOAP 1.1 Fault

<SOAP-ENV:Fault xmlns:sqlsoapfaultcode="https://schemas.microsoft.com/sqlserver/2004/SOAP/SqlSoapFaultCode">
  <faultcode>SOAP-ENV:Client</faultcode>
  <faultstring>There was an error in the incoming SOAP request packet:  Client, InvalidXml</faultstring>
  <faultactor>https://schemas.microsoft.com/sqlserver/2004/SOAP</faultactor>
  <detail xmlns:SOAP-1_2-ENV="http://www.w3.org/2003/05/soap-envelope">
    <SOAP-1_2-ENV:Code>
      <SOAP-1_2-ENV:Value>SOAP-1_2-ENV:Sender</SOAP-1_2-ENV:Value>
      <SOAP-1_2-ENV:Subcode>
         <SOAP-1_2-ENV:Value>sqlsoapfaultcode:InvalidXml</SOAP-1_2-ENV:Value>
      </SOAP-1_2-ENV:Subcode>
    </SOAP-1_2-ENV:Code>
    <SOAP-1_2-ENV:Reason>
      <SOAP-1_2-ENV:Text xml:lang="en-US">There was an error in the incoming SOAP request packet:  Sender, InvalidXml</SOAP-1_2-ENV:Text>
    </SOAP-1_2-ENV:Reason>
    <SOAP-1_2-ENV:Node>http://MyServer:80/sql</SOAP-1_2-ENV:Node>
    <SOAP-1_2-ENV:Role>https://schemas.microsoft.com/sqlserver/2004/SOAP</SOAP-1_2-ENV:Role>
    <SOAP-1_2-ENV:Detail>
      <sqlresultstream:SqlMessage xsi:type="sqlmessage:SqlMessage">
         <sqlmessage:Class>16</sqlmessage:Class>
         <sqlmessage:LineNumber>0</sqlmessage:LineNumber>
         <sqlmessage:Message>XML parsing: line 3, character 0, incorrect document syntax</sqlmessage:Message>
         <sqlmessage:Number>9422</sqlmessage:Number>
         <sqlmessage:Source>Microsoft-SQL/9.0</sqlmessage:Source>
         <sqlmessage:State>1</sqlmessage:State>
      </sqlresultstream:SqlMessage>
    </SOAP-1_2-ENV:Detail>
  </detail>
</SOAP-ENV:Fault>

Sample SOAP 1.2 Fault

SOAP-1_2-ENV:Fault xmlns:sqlsoapfaultcode="https://schemas.microsoft.com/sqlserver/2004/SOAP/SqlSoapFaultCode">
  <SOAP-1_2-ENV:Code>
    <SOAP-1_2-ENV:Value>SOAP-1_2-ENV:Sender</SOAP-1_2-ENV:Value>
    <SOAP-1_2-ENV:Subcode>
      <SOAP-1_2-ENV:Value>sqlsoapfaultcode:InvalidXml</SOAP-1_2-ENV:Value>
    </SOAP-1_2-ENV:Subcode>
  </SOAP-1_2-ENV:Code>
  <SOAP-1_2-ENV:Reason>
    <SOAP-1_2-ENV:Text xml:lang="en-US">There was an error in the incoming SOAP request packet:  Sender, InvalidXml</SOAP-1_2-ENV:Text>
  </SOAP-1_2-ENV:Reason>
  <SOAP-1_2-ENV:Node>http://MyServer:80/sql</SOAP-1_2-ENV:Node>
  <SOAP-1_2-ENV:Role>https://schemas.microsoft.com/sqlserver/2004/SOAP</SOAP-1_2-ENV:Role>
  <SOAP-1_2-ENV:Detail>
    <sqlresultstream:SqlMessage xsi:type="sqlmessage:SqlMessage">
      <sqlmessage:Class>16</sqlmessage:Class>
      <sqlmessage:LineNumber>0</sqlmessage:LineNumber>
      <sqlmessage:Message>XML parsing: line 3, character 0, incorrect document syntax</sqlmessage:Message>
      <sqlmessage:Number>9422</sqlmessage:Number>
      <sqlmessage:Source>Microsoft-SQL/9.0</sqlmessage:Source>
      <sqlmessage:State>1</sqlmessage:State>
    </sqlresultstream:SqlMessage>
  </SOAP-1_2-ENV:Detail>
</SOAP-1_2-ENV:Fault>

Examples

By default, SQL Server prepares SOAP 1.2 fault information. This includes additional fault information the SOAP 1.1 fault format does not support. Therefore, some additional SOAP 1.2 related fault details are embedded as overflow in the SOAP 1.1 <Details> node, where they can be parsed and retrieved by SOAP 1.1 client applications.

The following lines of example code demonstrate one possible method of parsing out this SOAP 1.2 fault information from a SOAP 1.1 fault returned by SQL Server. As it stands, this code is meant to be used as part of a C# console application.

To integrate parsing and retrieval of SOAP 1.2 fault details into your SOAP 1.1 application written in C#

  1. Copy the following code block to an existing function in your C# console application used to act as a SOAP 1.1 version client.

    try
    {
    ...
    }
    catch (System.Web.Services.Protocols.SoapException soapE)
    {
        // SOAP 1.1 Fault info
        Console.WriteLine("SOAP 1.1 fault...");
        Console.WriteLine("Code: " + soapE.Code.ToString());
        Console.WriteLine("Actor: " + soapE.Actor);
        Console.WriteLine("Detail: " + soapE.Detail.InnerXml);
    
        // Extract SOAP 1.2 Fault info from the Details node
        System.Xml.XmlNode fault12 = soapE.Detail;
    
    // Setup the namespace manager to use with XPath query
        System.Xml.NameTable nsTbl = new System.Xml.NameTable();
        System.Xml.XmlNamespaceManager nsMgr = new System.Xml.XmlNamespaceManager(nsTbl);
        nsMgr.AddNamespace("SOAP-1_2-ENV", "http://www.w3.org/2003/05/soap-envelope");
    
        Console.WriteLine("\r\nSOAP 1.2 fault...");
    
        // Fault Code
        // Using SelectNodes() method because SOAP 1.2 fault code are allowed to have sub-codes,
        // this way all the fault codes are retrieved at the same time.
        System.Xml.XmlNodeList myNodes = fault12.SelectNodes(".//SOAP-1_2-ENV:Value", nsMgr);
        foreach (System.Xml.XmlNode n in myNodes)
        {
            Console.WriteLine(n.ParentNode.LocalName + ": " + n.InnerText);
        }
    
        // Fault Reason
        // SOAP 1.2 fault reason can be in multiple languages which represented as sibling "Text" child
        // nodes under the "Reason" node
        myNodes = fault12.SelectNodes(".//SOAP-1_2-ENV:Reason/SOAP-1_2-ENV:Text", nsMgr);
        foreach (System.Xml.XmlNode n in myNodes)
        {
            Console.WriteLine(n.ParentNode.LocalName + ": " + n.InnerText);
        }
    
        // Fault Node
        System.Xml.XmlNode faulNode = fault12.SelectSingleNode(".//SOAP-1_2-ENV:Node", nsMgr);
        Console.WriteLine(faulNode.LocalName + ": " + faulNode.InnerText);
    
        // Fault Role
        faulNode = fault12.SelectSingleNode(".//SOAP-1_2-ENV:Role", nsMgr);
        Console.WriteLine(faulNode.LocalName + ": " + faulNode.InnerText);
    }
    
  2. Replace the contents of the try { ... } block with code that is used to send a SOAP 1.1 request message to SQL Server. If you have to, you can also replace the Console.WriteLine() method calls with a call to whatever method is appropriate for exception handling in your application.