withastro/astro · error · ActionError
CONTENT_TOO_LARGE
CONTENT_TOO_LARGE
Error message
Request body exceeds ${bodySizeLimit} bytes What it means
parseRequestBody reads the Content-Length header; if the declared body size is greater than the configured bodySizeLimit, the request is rejected before the body is read, with ActionError code CONTENT_TOO_LARGE (HTTP 413).
Source
Thrown at packages/astro/src/actions/runtime/server.ts:266
if (ctx.routePattern === ACTION_RPC_ROUTE_PATTERN) {
return { from: 'rpc', name: ctx.url.pathname.replace(/^.*\/_actions\//, '') } as const;
}
const queryParam = ctx.url.searchParams.get(ACTION_QUERY_PARAMS.actionName);
if (queryParam) {
return { from: 'form', name: queryParam } as const;
}
return undefined;
}
async function parseRequestBody(request: Request, bodySizeLimit: number) {
const contentType = request.headers.get('content-type');
const contentLengthHeader = request.headers.get('content-length');
const contentLength = contentLengthHeader ? Number.parseInt(contentLengthHeader, 10) : undefined;
const hasContentLength = typeof contentLength === 'number' && Number.isFinite(contentLength);
if (!contentType) return undefined;
if (hasContentLength && contentLength > bodySizeLimit) {
throw new ActionError({
code: 'CONTENT_TOO_LARGE',
message: `Request body exceeds ${bodySizeLimit} bytes`,
});
}
try {
if (hasContentType(contentType, formContentTypes)) {
if (!hasContentLength) {
const body = await readBodyWithLimit(request.clone(), bodySizeLimit);
const formRequest = new Request(request.url, {
method: request.method,
headers: request.headers,
body: toArrayBuffer(body),
});
return await formRequest.formData();
}
return await request.clone().formData();
}
if (hasContentType(contentType, ['application/json'])) {View on GitHub (pinned to d081033d5f)
Solutions
- Raise bodySizeLimit for the action/server config if larger payloads are legitimate.
- Reduce the payload size (paginate, compress, or split the request).
- Route large uploads through a dedicated file-upload endpoint or object storage instead of an action.
Example fix
// before - default limit rejects a 2MB JSON body
// astro.config / action config
export default defineConfig({
// ...
});
// after - raise the limit where the action/server is configured
// (set bodySizeLimit to a value above your max payload, e.g. 3MB) Defensive patterns
Strategy: validation
Validate before calling
// Reject oversized payloads before sending, based on a known limit.
const MAX = 1024 * 1024; // mirror the configured bodySizeLimit
const size = new Blob([JSON.stringify(payload)]).size;
if (size > MAX) throw new Error(`Payload ${size}B exceeds the ${MAX}B limit`); Try / catch
try {
await actions.upload(payload);
} catch (e) {
if (e instanceof ActionError && e.code === 'CONTENT_TOO_LARGE') {
// ask user to reduce size, or route to a file endpoint
} else throw e;
} Prevention
- Set bodySizeLimit deliberately to your real maximum payload.
- Compress or paginate large JSON payloads.
- Send large files to a dedicated upload endpoint, not an action.
When it happens
Trigger: An action request whose Content-Length exceeds the configured bodySizeLimit (the default cap applies when none is set).
Common situations: Uploading a large JSON payload or base64 file to a JSON action; increasing payload size without raising the limit; clients/proxies that report an accurate large Content-Length.
Related errors
- [astro:actions] `defineAction()` unexpectedly used on the cl
- [astro:actions] `getActionContext()` unexpectedly used on th
- BAD_REQUEST
- ActionCalledFromServerError
- Action not found: ${path}
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/3a1937d86ce1b46c.
Report an issue: GitHub.