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:
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
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 noContent-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.
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-Lengthrefuses 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.Troubleshooting
Related
- Prompt Compression — shrinking a body rather than refusing it
- Rate Limiter — a ceiling on how many requests arrive rather than how large they are
- Policies overview — scope, modes and policy chains
- Event schema — the fields each decision records