ProtocolException: The remote server returned an unexpected response: (400) Bad Request.
When making a request to a web-service the following
System.ServiceModel.ProtocolException is throw:
The remote server returned an unexpected response: (400) Bad Request.
in my case I was passing a large byte array to the web-service.
The "400 Bad Request" response is generated by the remote server hosting the web-service, and is caused simply because the request being sent to the remote server is too large. The default settings restrict the largest message to 65536 bytes, and the total message size is larger than this (or the current size setting).
Note: There may be other causes which I have not yet encountered.
- Reduce the size of the message being sent, i.e. reduce the amount of data being sent. For example if the data includes an image then can the quality (and thus size) of the image be reduced? (It is acknowledged that this is often not practical.)
- Consider streaming data to the web-service instead of loading it directly.
- The maximum receive message size at the remote server needs to
This is only an option is you are responsible for the web-service on
the remote web-server.
On the remote server edit the
web.configfile. To set the maximum receive message size first (i.) create a new binding which takes the new receive message size and then (ii.) associated that binding with the web-service.
Step 1. Create a new binding with the new receive message size
web.configfile add a new binding, and set the
maxReceivedMessageSizefor that binding to the desired value.
So if you wanted to be able to receive messages up to say 1MB (1,048,576 bytes) then you could add a binding similar to the following:
<binding name="Binding1" maxReceivedMessageSize="1048576"/>
The name "
Binding1" in the above is not significant, but it must be unique. So if you have multiple different bindings then each must have a unique name. A descriptive name might be better than the name I have used above. The
maxReceivedMessageSizevalue is specified in bytes.
Step 2. Associate that binding with the web-service
web.configfile add a service record, such as:
<endpoint address="" binding="basicHttpBinding"
namemust be the fully qualified name of the service. If you are not sure what this is then look in the corresponding .svc file and it should be the same as the name given there.
bindingConfigurationshould be set to the same name used when creating the binding with the larger
The contract should be the fully qualified name of the service contract class or interface.
Be aware that allowing larger requests does make the server more prone to possible denial of service requests. So consider carefully how large a request you will allow, and consider whether there might be a safer alternative.
These notes have been tested within Microsoft Visual Studio .NET 2010 (.NET 4), and may apply to other versions as well.
About the author: Brian Cryer is a dedicated software developer and webmaster. For his day job he develops websites and desktop applications as well as providing IT services. He moonlights as a technical author and consultant.