ProtocolException: There was an error deserializing the object of type Some.Type. The maximum array length quota (16384) has been exceeded while reading XML data.
When making a request to a web-service the following
System.ServiceModel.ProtocolException is throw:
The formatter threw an exception whlie trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:content. The InnerException message as 'There was an error deserializing the object of type Some.Type. The maximum array length quota (16384) has been exceeded while reading XML data.
Some.Type is the type of the array being passed.
In my case I was passing a large byte array to the web-service, and
the type was
The exception is generated by the remote server which is hosting the web-service, and is caused simply because there are limits placed on how large an array may be deserialized. This is to help prevent denial of service attacks on the server. The default limit being is set at an array size of 16384. So passing an array larger than this to a web service will cause this exception to be throw.
- Reduce the size of the array that is being passed. For example can you make do with two or more smaller requests rather than the current one?(I appreciate that this is often not practical.)
- The maximum array length quote limit 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 array length quota first (i.) create a new binding which takes the new max-array-length 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
maxArrayLengthfor that binding to the desired value.
In my case I am passing a byte array and I want to be able to pass binary data files, so I needed to be able to pass a quite large array. Do consider the practical implications of serializing and deserialzing large arrays! So if you wanted to be able to receive an array of up to 1,000,000 items (which is a lot!) then you could add a binding similar to the following:
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.
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 .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 arrays does make the server more prone to possible denial of service requests. So consider the implications of allowing larger arrays than the default and whether there is an alternative (i.e. safer) way of achieving what you are after.
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.