Management API - The request body XML was invalid or not correctly specified
Hi everyone,
I'm getting this error on changing configuration through the service management API: The request body XML was invalid or not correctly specified
The request body payload:
<?xml version="1.0" encoding="utf-8"?>
<ChangeConfiguration xmlns="http://schemas.microsoft.com/windowsazu
re">
<Configuration>PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxTZXJ2aWNlQ29uZmlndX
JhdGlvbiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIi
B4bWxuczp4c2Q9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxucz0iaHR0cDovL3
NjaGVtYXMubWljcm9zb2Z0LmNvbS9TZXJ2aWNlSG9zdGluZy8yMDA4LzEwL1NlcnZpY2VDb25maWd1cm
F0aW9uIiBzZXJ2aWNlTmFtZT0iIiBvc0ZhbWlseT0iMSIgb3NWZXJzaW9uPSIqIj4KICA8Um9sZSBuYW
1lPSJXZWJSb2xlMSI+CiAgICA8Q29uZmlndXJhdGlvblNldHRpbmdzPgogICAgICA8U2V0dGluZyBuYW
1lPSJNaWNyb3NvZnQuV2luZG93c0F6dXJlLlBsdWdpbnMuRGlhZ25vc3RpY3MuQ29ubmVjdGlvblN0cm
luZyIgdmFsdWU9IlVzZURldmVsb3BtZW50U3RvcmFnZT10cnVlIi8+CiAgICA8L0NvbmZpZ3VyYXRpb2
5TZXR0aW5ncz4KICAgIDxJbnN0YW5jZXMgY291bnQ9IjIiLz4KICAgIDxDZXJ0aWZpY2F0ZXMvPgogID
wvUm9sZT4KPC9TZXJ2aWNlQ29uZmlndXJhdGlvbj4K</Configuration>
</ChangeConfiguration>
Does anyone know why this error occurs? I suspect it has something to do with encoding but not sure.
I'm not sure, but I have just a general observation. If you're sending this as a HTTP POST with the content type of application/x-www-form-urlencoded the Configuration data has +'s in it that will most likely get parsed to spaces by the receiving server.
Shouldn't they be URL encoded to %2b?
Andy
I would verify that the configuration file is correct before you base64-encode it. It is a long time since I looked at all this but I vaguely remember encountering unexpected problems with the XML header - particularly to do with a need to use utf-8 not utf-16. This is all very vague so my apologies if I'm pointing you in the wrong direction.
Share your code?
One thing that surprised me was that a blank line at the top of the XML will cause an error (I think the same error text).
Does the code you're using ever work? (Is it something specific to this configuration change or this deployment that causes this? Or is it an issue with the way you're constructing the request?)
Always getting this error. The code is basically the following (using the Microsoft_Http_Client in the Windows Azure SDK for PHP):
$response = $this->_performRequest($operationUrl, '?comp=config',
Microsoft_Http_Client::POST,
array('Content-Type' => 'application/xml'),
'<?xml version="1.0" encoding="utf-8"?>
<ChangeConfiguration xmlns="http://schemas.microsoft.com/windowsazure">
<Configuration>' . base64_encode($configuration) . '</Configuration>
</ChangeConfiguration>');
I'm passing it the following configuration:
$configuration = '<?xml version="1.0" encoding="utf-8"?> <ServiceConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" serviceName="" osFamily="1" osVersion="*"> <Role name="WebRole1"> <ConfigurationSettings> <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true"/> </ConfigurationSettings> <Instances count="2"/> <Certificates/> </Role> </ServiceConfiguration>';
As a side note: the following does work (resetting storage keys):
$response = $this->_performRequest( self::OP_STORAGE_ACCOUNTS . '/' . $serviceName . '/keys', '?action=regenerate', Microsoft_Http_Client::POST, array('Content-Type' => 'application/xml'), '<?xml version="1.0" encoding="utf-8"?> <RegenerateKeys xmlns="http://schemas.microsoft.com/windowsazure"> <KeyType>' . ucfirst($key) . '</KeyType> </RegenerateKeys>');
I left a few additional suggestions on your StackOverflow post, but my main idea was to check if you are getting a requestId back in the call. If so, your request is valid to the API and the failure is at a higher level. The API will hand you back a x-ms-requestid header back, which you can toss to GetOperationStatus on the API and Azure will tell you why its mad at the request.
If you aren't getting that requestId back, the request itself is being dumped by the API before processing, which would be more of a data-contract-mismatch problem and you should make sure you are sending valid everything even to the extend of passing a valid base64 string that is not a valid config (just to ensure the API accepts the message)
Text from cross-post
Are you getting this directly from the call to the API? If so, it should be coming back with a x-ms-requestid header.
If you take that and call out to
https://management.core.windows.net/<subscriptionID/operations/<requestId>
This should give you a much more detailed message about what is going on, usually telling you exactly what is going on.
**** Cross posting my response to your question on Stack Overflow *****
Pardon my previous response. Upon looking closely at your XML file, I found that there is a space in this: xmlns="http://schemas.microsoft.com/windowsazu re" [Between windowsazu and re].
Please try removing the space and see if it helps.
Thanks
Gaurav Mantri
Cerebrata Software
1) Getting the config from Azure as ASCII (?), uploading it again as ASCII fails, uploading it as UTF-8 fails as well.
2) Works
3) Works
4) All I get is this lausy error (should create a T-Shirt from that :-)): "The request body XML was invalid or not correctly specified", even when passing it an ampty XML.
For the record: RAW request and response are:
-----------------------
Request
-----------------------
object(Microsoft_Http_Client)#3 (15) {
["adapter:protected"]=>
object(Microsoft_Http_Client_Adapter_Socket)#5 (6) {
["socket:protected"]=>
NULL
["connected_to:protected"]=>
array(2) {
[0]=>
NULL
[1]=>
NULL
}
["out_stream:protected"]=>
NULL
["config:protected"]=>
array(15) {
["persistent"]=>
bool(false)
["ssltransport"]=>
string(3) "ssl"
["sslcert"]=>
string(51) "C:\Projects\Workspaces\Default\Azure\management.pem"
["sslpassphrase"]=>
string(11) "*************"
["maxredirects"]=>
int(5)
["strictredirects"]=>
bool(false)
["useragent"]=>
string(21) "Microsoft_Http_Client"
["timeout"]=>
int(10)
["httpversion"]=>
string(3) "1.1"
["keepalive"]=>
bool(false)
["storeresponse"]=>
bool(true)
["strict"]=>
bool(true)
["output_stream"]=>
bool(false)
["sslusecontext"]=>
bool(true)
}
["method:protected"]=>
string(3) "POST"
["_context:protected"]=>
resource(38) of type (stream-context)
}
["uri:protected"]=>
object(Microsoft_Uri_Http)#10 (9) {
["_username:protected"]=>
string(0) ""
["_password:protected"]=>
string(0) ""
["_host:protected"]=>
string(27) "management.core.windows.net"
["_port:protected"]=>
int(443)
["_path:protected"]=>
string(97) "/******************/services/hostedservices/phptest1/deploymentslots/production"
["_query:protected"]=>
string(11) "comp=config"
["_fragment:protected"]=>
string(0) ""
["_scheme:protected"]=>
string(5) "https"
}
["headers:protected"]=>
array(3) {
["content-type"]=>
array(2) {
[0]=>
string(12) "Content-Type"
[1]=>
string(15) "application/xml"
}
["expect"]=>
array(2) {
[0]=>
string(6) "Expect"
[1]=>
string(0) ""
}
["x-ms-version"]=>
array(2) {
[0]=>
string(12) "x-ms-version"
[1]=>
string(10) "2009-10-01"
}
}
["method:protected"]=>
string(3) "POST"
["paramsGet:protected"]=>
array(0) {
}
["paramsPost:protected"]=>
array(0) {
}
["enctype:protected"]=>
NULL
["raw_post_data:protected"]=>
string(965) "<?xml version="1.0" encoding="utf-8"?>
<ChangeConfiguration xmlns="http://schemas.microsoft.com/windowsazure">
<Configuration>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPFNlcnZpY2VDb25maWd1cmF0aW9uIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL1NlcnZpY2VIb3N0aW5nLzIwMDgvMTAvU2VydmljZUNvbmZpZ3VyYXRpb24iIHNlcnZpY2VOYW1lPSIiIG9zRmFtaWx5PSIxIiBvc1ZlcnNpb249IioiPgogIDxSb2xlIG5hbWU9IldlYlJvbGUxIj4KICAgIDxDb25maWd1cmF0aW9uU2V0dGluZ3M+CiAgICAgIDxTZXR0aW5nIG5hbWU9Ik1pY3Jvc29mdC5XaW5kb3dzQXp1cmUuUGx1Z2lucy5EaWFnbm9zdGljcy5Db25uZWN0aW9uU3RyaW5nIiB2YWx1ZT0iVXNlRGV2ZWxvcG1lbnRTdG9yYWdlPXRydWUiLz4KICAgIDwvQ29uZmlndXJhdGlvblNldHRpbmdzPgogICAgPEluc3RhbmNlcyBjb3VudD0iMiIvPgogICAgPENlcnRpZmljYXRlcy8+CiAgPC9Sb2xlPgo8L1NlcnZpY2VDb25maWd1cmF0aW9uPgo=</Configuration>
</ChangeConfiguration>"
["auth:protected"]=>
NULL
["files:protected"]=>
array(0) {
}
["cookiejar:protected"]=>
NULL
["last_request:protected"]=>
NULL
["last_response:protected"]=>
NULL
["redirectCounter:protected"]=>
int(0)
}
-----------------------
Response
-----------------------
object(Microsoft_Http_Response)#9 (5) {
["version:protected"]=>
string(3) "1.1"
["code:protected"]=>
int(400)
["message:protected"]=>
string(11) "Bad Request"
["headers:protected"]=>
array(5) {
["Content-length"]=>
string(3) "230"
["Content-type"]=>
string(30) "application/xml; charset=utf-8"
["Server"]=>
string(21) "Microsoft-HTTPAPI/2.0"
["Date"]=>
string(29) "Thu, 17 Feb 2011 07:15:36 GMT"
["Connection"]=>
string(5) "close"
}
["body:protected"]=>
string(230) "<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Code>InvalidXmlRequest</Code><Message>The
request body’s XML was invalid or not correctly specified.</Message></Error>"
}
The serviceName attribute of the ServiceConfiguration element appears to be empty in the Service Configuration file. It is documented as:
Required. The name of the service. The name given here must match the name specified in the service definition file.
As Neil says, you are missing a service name.
To debug, copy the CSCONF and CSDEF into a real Visual Studio Azure project. You will get an error:
Warning 1 The 'name' attribute is invalid - The value '' is invalid according to its datatype 'http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition:NamedElementNameString' - The Pattern constraint failed. c:\dev\Blog\myProjName\myProjName\ServiceDefinition.csdef 2 26 myProjName
Error 2 The XML specification is not valid: The 'name' attribute is invalid - The value '' is invalid according to its datatype 'http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition:NamedElementNameString' - The Pattern constraint failed. c:\dev\Blog\myProjName\myProjName\ServiceDefinition.csdef 2 20 myProjName
Neil, Andy, no luck there... Have tried it but still receive the same error. FYI: when using the management portal, this is also blank and works perfectly.
Anyone from the Azure team who can see what's going on on the other end?
This is almost a stupid question, but I'll suggest it anyways:
Have you tried omitting the XML Declaration from the POST body?
I took your request and resent it via a wrapper class I have to a test role of my own. The only difference b/t your's and the working one for me is that the XML declaration is absent in the working request (since it can be derived from the http headers)
Maarten, believe it or not, I'm pretty sure the issue is that you're missing a slash at the end of your URL.
It should be: /<subscription-id>/services/hostedservices/phptest1/deploymentslots/production/?comp=config
I just tried dropping the slash, and I get the same error about the invalid request. I believe without that slash, the Service Management API is treating the request as a Create Deployment request (with a bogus but maybe ignored query string).
Thanks everyone! I've been reverse-engineering what the csmanage.exe sends over the wire, and it works now. Here's why:
As a side note: I noticed there's a "x-ms-version: 2010-04-01" in csmanage.exe. Any news/docs on that version?
PS: This will end up in the Windows Azure SDK for PHP if you want to see it working
Regarding "x-ms-version: 2010-04-01", see the MSDN topic Service Management Versioning for information about the versions.
|