Skip to main content
Applies to LLM and MCP — the Model Context Protocol your agents call tools over. An oversized body reaches the gateway before anything can judge it: it has to be read, buffered and parsed. Whether it came from a client that attached a PDF to a prompt by mistake or from someone probing for a way to exhaust memory, the cheapest defence is to refuse it by size before reading it. This is the plainest policy in the catalogue. It calls nothing, scores nothing and rewrites nothing. It measures two numbers and compares them.

Configure the policy

Open Policies → Library → Request Size Limiter.

Size limits

The form prints the resolved figure under the field — = 10,485,760 bytes. Read it, because of this:
The default of 10 megabytes can never fire. The gateway’s own HTTP layer refuses a body larger than 8 MiB — 8,388,608 bytes before any policy runs, and that wire limit is not configurable. Any Allowed Payload Size at or above 8,388,608 bytes is unreachable: the request is already gone by the time the policy would see it.So raising the setting buys you nothing — there is no headroom above 8 MiB to grant. The useful range is strictly below it, and the only reason to set this field at all is to refuse bodies the gateway would otherwise have accepted. Read the = N bytes line and keep it under 8,388,608.
A body over the wire limit is refused with 413 by the HTTP server, not by this policy. No policy runs, so no decision is recorded and the request’s Policies tab in Activity has nothing to show for it. A 413 with no decision behind it is the wire limit, not a misconfigured ceiling.The refusal carries the HTTP layer’s own default body, and it is not JSON: the content type is text/plain; charset=utf-8, the body is the literal string Request Entity Too Large, and the connection is closed straight after. A client that parses every error body as JSON will fail on this one rather than report it.

Character limits

It counts the whole body, not the prompt. Every character that arrived — JSON braces, field names, escape sequences, the full message history, tool definitions, tool results, base64 attachments. A 100,000-character ceiling is not a 100,000-character prompt; on a conversation of any depth it is considerably less. Measure a real request from your client before choosing a number.
Zero is not a valid ceiling, and the form lets you type it. The field’s minimum is 0 and clearing it counts as 0, which passes the console’s own check and is then refused by the gateway when you save, with the error A required field must be greater than zero. Leave the default, or enter a positive number.

Request validation

Reject undeclared content length — off by default. Refuses a request that carries no Content-Length header. Requiring Content-Length refuses chunked uploads and clients that stream a body of unknown size. That is the point — a declared size can be judged before the body is read — but it also refuses well-behaved clients that stream, so turn it on only where every caller is yours.
On MCP this setting refuses every tool call. An MCP tool call reaches the policy with no HTTP headers attached at all, so the header is always missing and the check always fires. If the policy’s scope touches any MCP application, leave this off.

Scope

Run it gateway-wide as a ceiling, and target a tighter one at applications whose traffic should be small. On a targeted policy the limit covers all of the application’s traffic, chat and MCP alike.
On MCP, “the body” is the tool call, not the HTTP request. What the policy measures is the tool name and the arguments it was called with — not the message wrapped around them, and not the bytes on the wire. A byte ceiling sized for an LLM conversation will never fire on MCP traffic; size it for the arguments you expect a tool to receive.

Mode

Enforce and Observe. In Observe the request is measured, recorded as over the limit, and passed through.

How the decision is made

The three checks run in this order, and the first to fire decides.
1

Content-Length, if you required it

No header, and the request is refused with 411 before anything is measured.In Observe the violation is recorded and the request continues to the checks below — it is not waved through.
2

Bytes

The body as received, against Allowed Payload Size. Over it, 413.
3

Characters

A body that passed the byte ceiling is counted in UTF-8 characters against Max Characters per request. Over it, 413.The two ceilings disagree in both directions, which is the reason to have both: a compact request can be small in bytes and still refused for length, and a body in a multi-byte script can hit the byte ceiling long before the character one.
4

Otherwise the request passes through untouched

The response carries what was measured and what the ceilings were.

What the caller receives

A refused request is answered before any provider is contacted: On MCP traffic the same refusals come back as an error carried inside a 200 response, under the code -32001 — a non-2xx would drop the client’s MCP session. Every request the policy lets through carries four headers describing what it measured: That includes requests that breached a ceiling in Observe: they are recorded as over the limit and then served with the headers set, so the figures are there for exactly the requests you most want to measure. Only a refusal — 411 or 413 in Enforce — goes back without them. They are the fastest way to size a ceiling, and they are not something the console shows you — they arrive on the response, where the application that made the request can read them. Run the policy in Observe with generous numbers, ask whoever maintains that application for the two measured figures, and set the ceilings from those.

Modes and failures

There is no external dependency to fail. This policy reads a byte slice already in memory: there is no store to be unreachable, no provider to time out, and nothing that can make it fail open or closed.

Limits

  • It cannot see anything larger than 8 MiB. The wire limit gets there first, and it is not configurable.
  • Request leg only. The size of the model’s answer is not checked, on any mode.
  • It measures the body as one blob. There is no per-field, per-message or per-attachment ceiling, and nothing distinguishes a long conversation from a single enormous prompt.
  • Character counting includes the serialisation, not just the text.
  • On MCP it measures the tool name and its arguments, not the HTTP request.
  • Requiring Content-Length refuses every MCP tool call and every chunked client.
  • It is not a substitute for model limits. Prompts that do not fit the resolved model are already rejected on the chat path. This policy is about not reading the body at all.
  • The refusal body is the gateway’s own shape, not your provider’s error shape, whichever wire format your client speaks.

Verify the policy

The Playground cannot exercise the ceilings. You type a prompt into it, not a payload, so it will never produce a body anywhere near a realistic limit. Step one is a console check and tells you the path works; everything after it needs a real request from whatever already calls this gateway, and making that request is your application’s side of the work, not something this page can walk you through.
1

Control — the path works at all

In the Playground, pick the application the policy applies to, and send:
Expect a normal reply. If this fails, the problem is the application, the model or the provider — not the policy. Fix it before going on.
2

Read what a normal request actually measures

Have a representative request sent from whatever normally calls this gateway, and ask whoever maintains it to read four headers off the response and pass them back to you:
The first two are what this request actually measured; the last two are the ceilings you set. Nothing in the console shows them, which is why this step has to be asked of someone else.This is the step that tells you whether your ceilings are set anywhere near real traffic. Do it before switching to Enforce, not after.
3

The byte ceiling refuses

Set Allowed Payload Size to something just under what step two measured, and send the same request again.Expect 413, and a refusal saying how many bytes arrived. Then confirm the model was never called: open Activity, click the request, open its Policies tab and read Aggregated Latency — the Provider row should be empty.
4

The character ceiling refuses independently

Restore the byte ceiling, then set Max Characters per request just under the character count from step two and send the request again.Expect 413 again, and a refusal naming the character count this time. That the message changed is the proof the second ceiling is doing its own work rather than the first firing twice.
Every decision this policy takes is recorded, in Observe mode too, where nothing is blocked. To read one, open Activity, click the request, and open its Policies tab: the policies chain lists this policy and the decision it made. The event schema is the reference for everything a decision records.

Troubleshooting