{"record":{"id":"3a1937d86ce1b46c","repo":"withastro/astro","slug":"content-too-large","errorCode":"CONTENT_TOO_LARGE","errorMessage":"Request body exceeds ${bodySizeLimit} bytes","messagePattern":"Request body exceeds (.+?) bytes","errorType":"exception","errorClass":"ActionError","httpStatus":413,"severity":"error","filePath":"packages/astro/src/actions/runtime/server.ts","lineNumber":267,"sourceCode":"\tif (ctx.routePattern === ACTION_RPC_ROUTE_PATTERN) {\n\t\treturn { from: 'rpc', name: ctx.url.pathname.replace(/^.*\\/_actions\\//, '') } as const;\n\t}\n\tconst queryParam = ctx.url.searchParams.get(ACTION_QUERY_PARAMS.actionName);\n\tif (queryParam) {\n\t\treturn { from: 'form', name: queryParam } as const;\n\t}\n\treturn undefined;\n}\n\nasync function parseRequestBody(request: Request, bodySizeLimit: number) {\n\tconst contentType = request.headers.get('content-type');\n\tconst contentLengthHeader = request.headers.get('content-length');\n\tconst contentLength = contentLengthHeader ? Number.parseInt(contentLengthHeader, 10) : undefined;\n\tconst hasContentLength = typeof contentLength === 'number' && Number.isFinite(contentLength);\n\n\tif (!contentType) return undefined;\n\tif (hasContentLength && contentLength > bodySizeLimit) {\n\t\tthrow new ActionError({\n\t\t\tcode: 'CONTENT_TOO_LARGE',\n\t\t\tmessage: `Request body exceeds ${bodySizeLimit} bytes`,\n\t\t});\n\t}\n\ttry {\n\t\tif (hasContentType(contentType, formContentTypes)) {\n\t\t\tif (!hasContentLength) {\n\t\t\t\tconst body = await readBodyWithLimit(request.clone(), bodySizeLimit);\n\t\t\t\tconst formRequest = new Request(request.url, {\n\t\t\t\t\tmethod: request.method,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tbody: toArrayBuffer(body),\n\t\t\t\t});\n\t\t\t\treturn await formRequest.formData();\n\t\t\t}\n\t\t\treturn await request.clone().formData();\n\t\t}\n\t\tif (hasContentType(contentType, ['application/json'])) {","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/actions/runtime/server.ts#L249-L285","documentation":"Astro enforces security.actionBodySizeLimit (default 1 MB) on action request bodies. When an incoming request carries a content-length header larger than the configured limit, the size is known before reading, so parseRequestBody rejects immediately with ActionError code CONTENT_TOO_LARGE — the body is never parsed.","triggerScenarios":"POSTing an action payload (JSON or form) whose declared content-length exceeds the limit — e.g. base64-encoded images or large text in a JSON action, or a multipart upload above 1 MB against the default.","commonSituations":"Adding image/file upload-through-actions features; embedding large generated content (reports, pasted documents) in action inputs; adapters or proxies that inflate the body (compression removed) pushing sizes just over the default.","solutions":["Raise the limit in astro.config.mjs: security: { actionBodySizeLimit: 10 * 1024 * 1024 } (10 MB in this example)","Reduce the payload: strip unneeded fields, paginate, or compress client-side","Move large uploads to a dedicated server endpoint (src/pages/api/*.ts) which has no action limit, and keep the action for metadata"],"exampleFix":"// before — astro.config.mjs defaults (1 MB), payload is 3 MB\n// after\nexport default defineConfig({\n  security: {\n    actionBodySizeLimit: 10 * 1024 * 1024, // 10 MB\n  },\n});","handlingStrategy":"validation","validationCode":"// check payload size before sending\nconst LIMIT = 1024 * 1024; // keep in sync with security.actionBodySizeLimit\nconst body = JSON.stringify(payload);\nif (body.length > LIMIT) {\n  throw new Error(`Payload ${body.length}B exceeds action limit ${LIMIT}B — use an endpoint`);\n}\nawait actions.importData(payload);","typeGuard":null,"tryCatchPattern":"try {\n  await actions.importData(payload);\n} catch (e) {\n  if (e instanceof ActionError && e.code === 'CONTENT_TOO_LARGE') {\n    // split the payload into chunks or move to a dedicated upload endpoint\n  } else throw e;\n}","preventionTips":["Set security.actionBodySizeLimit explicitly to your real maximum in astro.config.mjs","Never base64 large files into action payloads — use endpoints or object storage","Track typical payload sizes in dev to catch drift before production 413s"],"tags":["astro-actions","payload-size","content-too-large","security-config"],"backgroundTag":"request-body-too-large","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}