Webhook Error 413: Request Entity Too Large Rejects Automation Payloads
Fix webhook deliveries failing with HTTP 413 Payload Too Large: find the size limit in your proxy, gateway, or app, and handle oversized event payloads.
- #automation
- #devops
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
An HTTP 413 tells a webhook sender that the request body exceeded a size limit somewhere on the receiving path, so the automation behind the endpoint never runs. The sender sees:
HTTP/1.1 413 Request Entity Too Large
Content-Type: text/html
<html><head><title>413 Request Entity Too Large</title></head>
Or, behind nginx, in the receiver’s proxy log:
client intended to send too large body: 2411642 bytes, limit 1048576
The webhook source records a failed delivery and, depending on its policy, retries — repeatedly re-sending an oversized payload that will keep being rejected.
Symptoms
- Webhook deliveries fail with
413 Request Entity Too Largewhile small ones succeed. - Failures correlate with events that carry large payloads (bulk changes, big diffs, base64 blobs).
- The proxy/gateway log shows
client intended to send too large body ... limit N. - The sender’s delivery dashboard shows 413s and retry attempts for the same event.
- The application handler never logs the request — it is rejected upstream.
Common Root Causes
- Reverse proxy body limit — nginx
client_max_body_size(default 1m) or similar caps the body before it reaches the app. - API gateway / load balancer limit — cloud gateways cap request payload size (e.g. ~10 MB for many, ~256 KB for some serverless triggers).
- Application framework limit — body-parser/JSON size limits (Express
limit, SpringmaxRequestSize) reject large bodies. - Serverless payload cap — the function invocation has a hard payload ceiling smaller than the event.
- Genuinely oversized events — the source batches or inlines large data (attachments, full snapshots) into the webhook body.
- Ingress/WAF limits — a Kubernetes ingress annotation or WAF rule caps request size.
Diagnostic Workflow
Confirm the rejection and which hop produced it:
curl -sS -o /dev/null -w '%{http_code}\n' -X POST https://hooks.example.com/ingest \
-H 'Content-Type: application/json' --data-binary @large-payload.json
Measure the real payload size the sender is sending:
wc -c large-payload.json
# compare against each limit below
Check the nginx / proxy limit and its logs:
grep -Rn 'client_max_body_size' /etc/nginx/
grep -i 'too large body' /var/log/nginx/error.log | tail
For Kubernetes ingress, inspect the size annotation:
kubectl get ingress <name> -o jsonpath='{.metadata.annotations}' | jq \
| grep -i 'proxy-body-size'
Check the application framework’s configured limit (example: Express):
grep -RnE 'express.json\(|bodyParser|limit:' src/
Example Root Cause Analysis
A GitHub webhook that triggered a CI mirror started failing on large pushes. Small pushes worked; a push touching hundreds of files returned 413. The receiver ran behind nginx, whose error log showed:
client intended to send too large body: 2411642 bytes, limit 1048576
The payload was ~2.4 MB but nginx’s default client_max_body_size is 1 MB. The request was rejected at the proxy and never reached the Node app, so the app logs were empty — which had made it look like the app was “silently dropping” events.
The fix raised the proxy limit to comfortably cover the source’s documented maximum payload and matched the app’s body-parser limit to it:
# nginx
client_max_body_size 25m;
# express
app.use(express.json({ limit: '25mb' }));
Both limits had to move together: raising only nginx would have pushed the 413 down to Express instead. GitHub’s redelivery of the previously-failed events then succeeded. To avoid unbounded growth, the team also added a hard cap above the source’s real maximum and a clear 413 response so a truly abusive payload is still rejected deliberately rather than by accident.
Prevention Best Practices
- Set body-size limits at every hop (proxy, gateway, ingress, app) consistently, sized to the source’s documented maximum payload plus headroom.
- Raise all limits on the path together — a mismatch just moves the 413 to the next hop.
- Prefer webhook payloads that carry a reference/ID and let the consumer fetch large data, instead of inlining big blobs.
- Return a clear
413with a helpful body so senders and logs show the real cause, not a generic proxy page. - Alert on 413 rates so a change in event size is caught before deliveries are lost to retries.
- Keep a deliberate upper bound so oversized or malicious payloads are rejected on purpose, not accidentally.
Quick Command Reference
# Reproduce and read the status code
curl -sS -o /dev/null -w '%{http_code}\n' -X POST <url> \
--data-binary @large-payload.json
# Measure payload size
wc -c large-payload.json
# nginx limit + logs
grep -Rn 'client_max_body_size' /etc/nginx/
grep -i 'too large body' /var/log/nginx/error.log
# Kubernetes ingress body-size annotation
kubectl get ingress <name> -o jsonpath='{.metadata.annotations}' | jq
Conclusion
A webhook 413 is a size limit somewhere on the receiving path, not a bug in the sender. The trap is that the rejection often happens at a proxy or gateway before your application ever sees the request, so the logs look empty. Trace the limits at every hop, raise them together to cover the source’s real maximum payload plus headroom, and keep a deliberate upper bound. Where you can, redesign events to pass a reference the consumer fetches rather than inlining large data — that keeps payloads small and 413s away for good.
Fixed it? Get 500 Automation & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.