Cry about...
MS-Windows Troubleshooting


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.


Symptom:

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.

where 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 System.Byte[].

Cause:

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.

Possible Remedies:

  • 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 be changed. 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.config file. 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

    In the web.config file add a new binding, and set the maxArrayLength for 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:

    <configuation>
     .
     .
     <system.serviceModel>
      .
      .
      <bindings>
       <basicHttpBinding>
        <binding name="Binding1">
          <readerQuotas maxArrayLength="1000000"/>
        </binding>

       </basicHttpBinding>
      </bindings>
      .
      .
     </system.serviceModel>
    </configuration>

    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

    In the web.config file add a service record, such as:

    <configuation>
     .
     .
     <system.serviceModel>
      .
      .
      <services>
       <service name="MyService">
        <endpoint address="" binding="basicHttpBinding"
         bindingConfiguration="Binding1"
         contract="IMyService"/>
       </service>

      </services>
      .
      .
     </system.serviceModel>
    </configuration>

    The service name must 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.

    The bindingConfiguration should be set to the same name used when creating the binding with the larger maxArraySize.

    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: 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.