# Monday, April 08, 2013
« The Architecture of WCF | Main |

If you have been working with WCF for a while you may have noticed that, by default, messages over a certain size fail to get processed. The reason for this is that WCF tries to protect the message receiver from getting swamped with messages that will consume huge amounts of memory to process. The thing that controls this is the maxReceivedMessageSize on the binding which defaults to 64Kb.

Notice that maxReceivedMessageSize is only about the receiver of the message, it doesn’t stop you sending a very large message. The idea is that the sender is in control of what they send whereas the receiver has no way to control the size of message it is being asked to deal with. There is no built in way to limit the size of a message on the sender side, although you could use a MessageInspector for this purpose as long as the message wasn’t being streamed.

However, there are two ways to send messages: buffering and streaming. Buffered messages get fully buffered in the channel layer before being handed to the service model layer whereas streamed messages only buffer the SOAP headers and then pass the body as a stream to the service model layer (this requires a service contract designed for streaming).

Depending on the binding you may be able to change the maximum size of message that can be dealt with purely by changing maxReceivedMessageSize however, for bindings that support streaming (e.g. BasicHttpBinding) there is a second binding parameter that may have to change - the maxBufferSize. If you are buffering messages then the maxReceivedMessageSize and maxBufferSize must be the same. When streaming the maxBufferSize must be large enough to buffer the headers.

Once the binding allows messages larger than 64Kb that may not be the whole story as there are other default limits in WCF: quotas and serializer limits. The quotas control the maximum size of things like arrays and strings and are controlled by the <readerQuotas> element under the binding. The serializer limit for the DataContractSerializer limits the maximum number of objects in the object graph and is controlled by the DataContractSerializer service behavior. Prior to WCF 4.5 these values often needed adjusting for large messages. However, in WCF 4.5 these values were all defaulted to int.MaxValue as the maxReceivedMessageSize already provides default protection.

If you suspect you are hitting on of these limits the quickest way normally to diagnose this is to turn on tracing (I recorded a screencast here showing how). It will show which limit has been breached.

One final word on default endpoints introduced in WCF 4.0.If you have changed all the relevant values and you are still seeing the maxRecevedMessageSize stopping your messages make sure that you service config has the right name for the service. If not, and you have a base address, the default endpoint functionality will use a set of defaults anyway, ignoring your carefully crafted values.