wcf-errorstroubleshootingweb-services

Fix: The Maximum Message Size Quota for Incoming Messages (65536) Has Been Exceeded

SOAPless Team7 min read

If you've ever called a WCF service and received the error "The maximum message size quota for incoming messages (65536) has been exceeded", you know how abruptly it kills an otherwise working integration. The service is reachable, your request is valid, and smaller payloads work fine — but the moment a response crosses 64 KB, the channel faults and everything stops.

This guide explains exactly why the error occurs, how to fix it on both the client and server side, and how to avoid related pitfalls like buffer size mismatches and memory exhaustion.

Understanding the Error

The full exception typically reads:

System.ServiceModel.CommunicationException:
The maximum message size quota for incoming messages (65536) has been exceeded.
To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.

WCF imposes a default cap of 65,536 bytes (64 KB) on incoming messages for every binding. This is a deliberate security measure — it prevents a malicious or misconfigured service from flooding clients with enormous payloads that could exhaust memory.

The key word here is incoming. On the client side, "incoming" means the response from the server. On the server side, "incoming" means the request from the client. You need to raise the limit on whichever side is receiving the oversized message.

Fix 1: Increase MaxReceivedMessageSize on the Client

The most common scenario is a client receiving a large response. Open your app.config or web.config and locate the binding configuration:

<system.serviceModel>
  <bindings>
    <basicHttpBinding>
      <binding name="LargeMessageBinding"
               maxReceivedMessageSize="10485760"
               maxBufferSize="10485760">
        <readerQuotas maxDepth="64"
                      maxStringContentLength="2147483647"
                      maxArrayLength="2147483647"
                      maxBytesPerRead="4096"
                      maxNameTableCharCount="16384" />
      </binding>
    </basicHttpBinding>
  </bindings>
  <client>
    <endpoint address="http://example.com/MyService.svc"
              binding="basicHttpBinding"
              bindingConfiguration="LargeMessageBinding"
              contract="IMyService" />
  </client>
</system.serviceModel>

The critical properties are:

  • maxReceivedMessageSize — The absolute maximum size in bytes for an incoming message. Setting this to 10485760 allows responses up to 10 MB.
  • maxBufferSize — Must be equal to or greater than maxReceivedMessageSize when using buffered transfer mode (the default). If these two values don't match, WCF throws a separate ArgumentException.
  • readerQuotas — Controls XML reader limits. Large SOAP responses with deep nesting or huge string values may also hit maxStringContentLength or maxArrayLength limits even after you raise the message size.

Common Mistake: Mismatched Binding Configuration Name

A frequent cause of "I already increased the size but still get the error" is a mismatch between the bindingConfiguration attribute on the endpoint and the name attribute on the binding. If they don't match, WCF silently falls back to default settings (64 KB). Double-check that these strings are identical.

Fix 2: Increase MaxReceivedMessageSize on the Server

If clients are sending large requests (for example, uploading files or submitting bulk data through a SOAP operation), the server also needs its binding configured:

<system.serviceModel>
  <bindings>
    <basicHttpBinding>
      <binding name="LargeRequestBinding"
               maxReceivedMessageSize="10485760"
               maxBufferSize="10485760">
        <readerQuotas maxDepth="64"
                      maxStringContentLength="2147483647"
                      maxArrayLength="2147483647"
                      maxBytesPerRead="4096"
                      maxNameTableCharCount="16384" />
      </binding>
    </basicHttpBinding>
  </bindings>
  <services>
    <service name="MyNamespace.MyService">
      <endpoint address=""
                binding="basicHttpBinding"
                bindingConfiguration="LargeRequestBinding"
                contract="MyNamespace.IMyService" />
    </service>
  </services>
</system.serviceModel>

After changing the server configuration, restart the service or recycle the application pool in IIS.

Fix 3: Binding-Specific Configuration

Different WCF bindings have the same property names but require separate configuration sections. Here are the most common ones:

wsHttpBinding

<wsHttpBinding>
  <binding name="LargeWsHttp"
           maxReceivedMessageSize="10485760"
           maxBufferPoolSize="10485760">
    <readerQuotas maxStringContentLength="2147483647"
                  maxArrayLength="2147483647" />
  </binding>
</wsHttpBinding>

Note that wsHttpBinding does not have maxBufferSize because it always uses buffered transfer mode internally. Use maxBufferPoolSize instead to control the buffer pool.

netTcpBinding

<netTcpBinding>
  <binding name="LargeNetTcp"
           maxReceivedMessageSize="10485760"
           maxBufferSize="10485760"
           maxBufferPoolSize="10485760">
    <readerQuotas maxStringContentLength="2147483647"
                  maxArrayLength="2147483647" />
  </binding>
</netTcpBinding>

customBinding

If you're using a custom binding, you need to set the limit on the transport binding element:

<customBinding>
  <binding name="LargeCustom">
    <textMessageEncoding messageVersion="Soap11" />
    <httpTransport maxReceivedMessageSize="10485760"
                   maxBufferSize="10485760" />
  </binding>
</customBinding>

Fix 4: Use Streamed Transfer Mode for Very Large Messages

When messages exceed tens of megabytes, buffering the entire payload in memory becomes expensive. WCF supports a streamed transfer mode that processes the message as a stream without loading it entirely into memory:

<basicHttpBinding>
  <binding name="StreamedBinding"
           transferMode="Streamed"
           maxReceivedMessageSize="104857600">
    <!-- maxBufferSize stays small in streamed mode -->
    <!-- It only buffers the SOAP headers, not the body -->
    <readerQuotas maxStringContentLength="2147483647" />
  </binding>
</basicHttpBinding>

The transferMode property accepts four values:

ValueRequestResponse
Buffered (default)BufferedBuffered
StreamedStreamedStreamed
StreamedRequestStreamedBuffered
StreamedResponseBufferedStreamed

Important constraints for streamed mode:

  • The service operation must accept or return a Stream or Message parameter — you cannot stream arbitrary complex types.
  • maxBufferSize in streamed mode controls only the SOAP header buffer, so keep it small (e.g., 65536).
  • Reliable sessions and transport-level security are limited in streamed mode.

Fix 5: Programmatic Configuration

If you create your WCF client in code rather than config files (common in dynamically-generated proxies), set the binding properties programmatically:

var binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = 10 * 1024 * 1024; // 10 MB
binding.MaxBufferSize = 10 * 1024 * 1024;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;

var endpoint = new EndpointAddress("http://example.com/MyService.svc");
var client = new MyServiceClient(binding, endpoint);

This approach is especially useful in test harnesses or when you need to adjust limits at runtime based on the expected payload size.

Diagnostic Steps

If you've changed the configuration but the error persists, walk through this checklist:

  1. Verify the correct config file is being loaded. Console apps use app.config, web apps use web.config. If you have multiple config files (e.g., a class library with its own config), only the hosting application's config is used.

  2. Confirm the binding configuration name matches. Run a case-sensitive comparison between bindingConfiguration on the endpoint and name on the binding element.

  3. Check both client AND server. If you control both sides, ensure both have adequate limits. The error message is identical whether the client or server rejects the message.

  4. Enable WCF tracing to see the actual message size:

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel" switchValue="Warning">
      <listeners>
        <add name="traceListener"
             type="System.Diagnostics.XmlWriterTraceListener"
             initializeData="c:\logs\wcf-trace.svclog" />
      </listeners>
    </source>
  </sources>
</system.diagnostics>
  1. Measure the actual response size with a tool like Fiddler or Wireshark. Sometimes the response is far larger than expected due to verbose XML serialization or base64-encoded binary data.

Security Considerations

Don't blindly set maxReceivedMessageSize to int.MaxValue (2,147,483,647 bytes = 2 GB) in production. This disables the denial-of-service protection that the default limit provides. Instead:

  • Estimate the realistic maximum response size for each operation.
  • Add a reasonable margin (2x to 5x the expected maximum).
  • Monitor memory usage under load after increasing limits.
  • Use streamed transfer mode for genuinely large payloads rather than raising the buffer limit.

How SOAPless Helps

Dealing with WCF message size quotas means wrestling with XML config files, matching binding names, and redeploying after every change. If you're consuming a SOAP service from a modern application, consider whether this complexity is worth maintaining.

SOAPless converts any WSDL-based SOAP service into a clean REST JSON API. You paste your WSDL URL, and SOAPless generates RESTful endpoints automatically. Large responses are handled transparently — no binding configuration, no buffer size tuning, no config file debugging. Authentication credentials are encrypted and managed through the dashboard, and you get an OpenAPI spec you can use with any HTTP client.

If WCF configuration is consuming more of your time than the actual business logic, try SOAPless and skip the plumbing entirely.