I'm going to assume you are using the WS-I compliant SOAP API v2 as I had this exact same issue; if not, then this still might apply. I was never able to connect to the v2 API without it being WS-I compliant, which is how I found this bug.
If you have a look at the app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php file you will see in the public run function that is essentially split into two parts - 1 for the WSDL definition response and 1 for the actual SOAP response.
In the SOAP response there is a bit of string replacing going on, substituting <soap:operation soapAction=""></soap:operation> for <soap:operation soapAction="" /> and so on. This is evidently causing an issue with the content-length calculation - this is also occurring in the WSDL definition response, but it doesn't seem to be causing an issue.
I was able to successfully connect to the SOAP API by replacing the code between the try curly brackets with the code below. Basically, I ended up clearing the headers and recalculating the content-length AFTER the string replacement had taken place:
$content = preg_replace(
"<soap:operation soapAction=\"\" />\n",
"<soap:body use=\"literal\" />\n",
'<?xml version="$1" encoding="'.$apiConfigCharset.'"?>',
This is super thanks, I am using v2 and so I had to change another file. Unfortunately I am still getting the same issue, one byte is still going missing, is there anywhere else that the body could be being changed?
BTW a quick fix at the moment is ->setHeader('Content-Length',strlen($content)-1)
@Zyava - quite possibly, I didn't enter the link in my comments (which I normally do for this exact reason) and it was over a year ago that I had the issue
I am marking this as the correct answer, I was using the v2 API and so for reference I will create an answer below which includes the fix for that situation. All of my requests were out by 1 byte and so the -1 fix works well for me, I can't understand where that byte is going, but I have more important things in life.