This error is not about malformed XML. It is about a SOAP version mismatch between the client and the server.
The content type application/soap+xml; charset=utf-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8)
In plain terms: one side is speaking SOAP 1.2 while the other expects SOAP 1.1. The HTTP-level Content-Type is how SOAP clients detect this disagreement before they even parse the envelope.
SOAP 1.1 vs SOAP 1.2: the key differences
Understanding the protocol differences is the fastest way to diagnose this error.
| Aspect | SOAP 1.1 | SOAP 1.2 |
|---|---|---|
| Content-Type | text/xml; charset=utf-8 | application/soap+xml; charset=utf-8 |
| Action header | SOAPAction HTTP header | action parameter inside Content-Type |
| Envelope namespace | http://schemas.xmlsoap.org/soap/envelope/ | http://www.w3.org/2003/05/soap-envelope |
| Fault structure | <faultcode> + <faultstring> | <Code> + <Reason> with subcodes |
| Binding transport | http://schemas.xmlsoap.org/soap/http | http://www.w3.org/2003/05/soap/bindings/HTTP/ |
When your client generates a request with text/xml (SOAP 1.1) but the server responds with application/soap+xml (SOAP 1.2), the client library rejects the response immediately — before it even looks at the XML body.
Step 1: Check the WSDL binding
The WSDL tells you which SOAP version the service expects. Look for the <binding> element and its transport attribute.
SOAP 1.1 binding example:
<wsdl:binding name="UserServiceSoap" type="tns:UserServiceSoap">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetUser">
<soap:operation soapAction="http://tempuri.org/GetUser" />
<!-- ... -->
</wsdl:operation>
</wsdl:binding>
SOAP 1.2 binding example:
<wsdl:binding name="UserServiceSoap12" type="tns:UserServiceSoap">
<soap12:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetUser">
<soap12:operation soapAction="http://tempuri.org/GetUser" />
<!-- ... -->
</wsdl:operation>
</wsdl:binding>
The namespace prefix tells you which version: soap: typically maps to the SOAP 1.1 namespace, while soap12: maps to the SOAP 1.2 namespace. Many services expose both bindings on different ports or endpoints.
Step 2: Verify with curl
Before touching client code, confirm what the server actually returns.
# Check what Content-Type the server sends back
curl -s -D - -o /dev/null \
-H "Content-Type: text/xml; charset=utf-8" \
-H 'SOAPAction: "http://tempuri.org/GetUser"' \
-d '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUser xmlns="http://tempuri.org/">
<userId>1</userId>
</GetUser>
</soap:Body>
</soap:Envelope>' \
https://example.com/service.svc
Look at the Content-Type in the response headers. If you sent text/xml but the response contains application/soap+xml, the server is responding with SOAP 1.2. You need to either switch your client to SOAP 1.2, or find the SOAP 1.1 endpoint.
# Try the SOAP 1.2 Content-Type instead
curl -s -D - -o /dev/null \
-H "Content-Type: application/soap+xml; charset=utf-8; action=\"http://tempuri.org/GetUser\"" \
-d '<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetUser xmlns="http://tempuri.org/">
<userId>1</userId>
</GetUser>
</soap12:Body>
</soap12:Envelope>' \
https://example.com/service.svc
Step 3: Fix the client configuration
WCF (.NET) — web.config / app.config
The most common source of this error is a WCF client using basicHttpBinding (SOAP 1.1) against a service that expects wsHttpBinding or a custom SOAP 1.2 binding.
<!-- Wrong: basicHttpBinding uses SOAP 1.1 (text/xml) -->
<bindings>
<basicHttpBinding>
<binding name="UserServiceSoap" />
</basicHttpBinding>
</bindings>
<!-- Correct: use customBinding with SOAP 1.2 textMessageEncoding -->
<bindings>
<customBinding>
<binding name="UserServiceSoap12">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
</customBinding>
</bindings>
Alternatively, if the server actually supports SOAP 1.1, verify the endpoint address points to the SOAP 1.1 port:
<client>
<endpoint address="https://example.com/service.svc/soap11"
binding="basicHttpBinding"
bindingConfiguration="UserServiceSoap"
contract="UserService.IUserService" />
</client>
Java (JAX-WS)
In Java, the SOAP version is controlled by the @BindingType annotation on the service side, or by specifying the binding ID when creating the client.
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.SOAPBinding;
// Force SOAP 1.2 on the client side
UserService service = new UserService();
UserServiceSoap port = service.getUserServiceSoap12();
BindingProvider bp = (BindingProvider) port;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
// binding is already SOAP 1.2 if the port was generated from a SOAP 1.2 WSDL binding
// Or explicitly set the endpoint if needed
bp.getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"https://example.com/service"
);
When regenerating client stubs from WSDL, make sure wsimport or your build plugin picks up the correct binding.
.NET (modern HttpClient approach)
If you are building requests manually without WCF:
// For SOAP 1.2
var content = new StringContent(soapEnvelope, Encoding.UTF8, "application/soap+xml");
// For SOAP 1.1
var content = new StringContent(soapEnvelope, Encoding.UTF8, "text/xml");
request.Headers.Add("SOAPAction", "\"http://tempuri.org/GetUser\"");
Why teams keep hitting this
The "works in SoapUI but not in code" scenario happens because different tools silently pick different bindings. SoapUI may auto-select the SOAP 1.2 port, while your generated client defaults to the SOAP 1.1 port. The error only surfaces at runtime.
This gets worse when the WSDL exposes both versions and each consumer independently discovers which one works. There is no single source of truth.
How SOAPless eliminates this problem
When you register a WSDL with SOAPless, the engine parses the WSDL, detects whether the service uses SOAP 1.1 or SOAP 1.2, and automatically uses the correct Content-Type, envelope namespace, and action header format for every request. Your downstream consumers just call a REST JSON endpoint — they never need to think about text/xml versus application/soap+xml.
If the service exposes multiple SOAP versions, SOAPless pins the correct binding at registration time so the mismatch cannot happen downstream.