koala73/worldmonitor · error · Error
payload_too_large
Error message
payload_too_large
What it means
Thrown by readBodyWithLimit() in the security report edge function when the Content-Length request header is present, finite, and exceeds MAX_REPORT_BYTES (32 KB / 32768 bytes). This is the fast-path rejection — the body is never read, saving edge function execution time and memory. The function is used to protect the CSP/COEP/CORP violation-reporting endpoint from oversized payloads.
Source
Thrown at api/security/report.js:68
effectivePolicy: shortString(body.effectivePolicy, 120),
blockedURLOrigin: safeOrigin(body.blockedURL),
destination: shortString(body.destination, 80),
};
}
function summarizeReports(payload) {
const reports = Array.isArray(payload) ? payload : [payload];
return {
count: reports.length,
truncated: reports.length > MAX_REPORT_ITEMS,
reports: reports.slice(0, MAX_REPORT_ITEMS).map(summarizeReportItem),
};
}
async function readBodyWithLimit(req) {
const contentLength = Number(req.headers.get('content-length') ?? 0);
if (Number.isFinite(contentLength) && contentLength > MAX_REPORT_BYTES) {
throw new Error('payload_too_large');
}
if (!req.body) return '';
const reader = req.body.getReader();
const chunks = [];
let total = 0;
while (true) {
const { value, done } = await reader.read();
if (done) break;
total += value.byteLength;
if (total > MAX_REPORT_BYTES) {
await reader.cancel();
throw new Error('payload_too_large');
}
chunks.push(value);View on GitHub (pinned to ffec79ac33)
Solutions
- Reduce the report payload to under 32 KB — send fewer reports per POST, or split a large batch into multiple requests (MAX_REPORT_ITEMS is 20).
- If the report is a single oversized item, trim or summarize it client-side before sending.
- If legitimate traffic routinely exceeds 32 KB, consider raising MAX_REPORT_BYTES (but weigh edge function memory/execution limits).
- Clients should set a batch flush timer or count limit so they never accumulate >32 KB before POSTing.
Example fix
// before — client sends 500 reports in one POST (>32KB)
fetch('/api/security/report', { method: 'POST', body: JSON.stringify(allReports) })
// after — batch into chunks of 20
for (let i = 0; i < allReports.length; i += 20) {
await fetch('/api/security/report', { method: 'POST', body: JSON.stringify(allReports.slice(i, i + 20)) });
} Defensive patterns
Strategy: validation
Validate before calling
// Validate payload size before POSTing to the report endpoint
const MAX_REPORT_BYTES = 32 * 1024; // 32 KB — mirror the server limit
const MAX_REPORT_ITEMS = 20;
function batchReports(reports) {
return reports.slice(0, MAX_REPORT_ITEMS).map(r => JSON.stringify(r)).join('');
}
const serialized = batchReports(myReports);
if (new Blob([serialized]).size > MAX_REPORT_BYTES) {
// Split into smaller batches
const chunks = chunkArray(myReports, 10); // halve the batch
for (const chunk of chunks) {
await postReport(chunk);
}
} else {
await postReport(myReports);
} Prevention
- Set a Content-Length header on report POSTs so the server can fast-reject oversized payloads.
- Batch reports to at most 20 items per POST (MAX_REPORT_ITEMS).
- Monitor client-side payload size and split before sending if approaching 32 KB.
When it happens
Trigger: POSTing to /api/security/report with a Content-Length header greater than 32768 bytes. This could be a single very large report or an array of reports whose total serialized size exceeds 32 KB. The check uses the header value before any body reading, so even a streaming body is never consumed.
Common situations: A browser sending a large violation report batch (many CSP violations in one POST); a malicious or buggy client sending an oversized payload; a reporting client that does not batch-limit its reports; a misconfigured report endpoint collecting too many violations before flushing.
Related errors
- URL protocol not allowed
- Redirect to disallowed domain
- Redis not configured
- Webhook URL must not point to a metadata endpoint
- Webhook URL must not point to a private/local address
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/2a4bd343a8aad207.
Report an issue: GitHub.