How to Handle HTTP 413 Errors When Uploading Files to an API
When an API rejects a file upload with HTTP 413, the request body has exceeded a size limit enforced by the server…
A webhook provider sends an HTTP request to your endpoint when an event occurs, such as a payment update or account change. Your server must respond before the provider’s deadline. A timeout means the provider did not receive a response in time; a 500 error means it received a server-error response. Both can cause a delivery attempt to fail and the provider to send the event again.
Each provider sets its own response deadline and retry rules. First, check what response the provider recorded and compare it with your server logs. This comparison shows whether the provider retried a failed delivery and whether the failure happened before the request reached your code, while your code handled it, or after your endpoint sent a response.
HTTP status codes tell the sender how a request ended: 2xx (200 or 202) indicates success, while 5xx (500 or 503) indicates a server-side error. A timeout means the provider did not receive a response before its own time limit.
Each provider sets its own response deadline and rules for retrying failed requests. Roark’s webhook documentation specifies a five-second response limit and says it retries when an endpoint does not return 2xx. The University of Wisconsin–Madison’s Person API specifies a ten-second limit and says it resends events rejected with 401. Check the documentation for the provider that sent the request. The examples show that timeout limits and failure rules vary by provider.
A 500 is a response, while a timeout is the absence of a timely response. In either case, the provider may classify the attempt as unsuccessful. Roark, for example, retries after a non-2xx response; its documented policy includes up to three retries with exponential backoff, meaning the wait between retries increases. Other providers use different rules. A 4xx response also does not have one universal outcome: the UW–Madison documentation describes resending after 401, but you should verify how your provider handles each status code.
The provider’s record shows what happened from its point of view, but it may not identify which component produced the result. A 502 or 504, for example, might come from a gateway or proxy between the provider and your endpoint. Check the provider’s delivery details for the recorded status, response body, and timing, then compare them with your own request logs.
Use the provider’s delivery history to identify one failed attempt and its timestamp. Then search your server, load balancer, or proxy logs for that same request. If the provider records a timeout but your server has no matching request, investigate the path to the endpoint. Confirm that the URL is correct, its domain name resolves to an address, the network allows access, and any proxy or gateway in front of the server passes the request through. If the request appears in the load balancer or proxy logs but not in your service logs, check how that load balancer or proxy routes or rejects the request.
If your logs show a 500, follow the request into the handler and find the first exception or failed dependency call. Check whether the error began after a deployment or configuration change, and whether the handler failed on every event or only on a particular payload or downstream service. If the provider records a 5xx but your application logs show a successful response, compare timestamps and request identifiers across the application and intermediary logs. A proxy can return an error even when the application later completes its work.
If the provider records a timeout and your logs show the handler eventually returned 2xx, the endpoint responded too late for that provider’s deadline. Measure how much time the handler spends on database queries and external API calls. Include any other work it does before responding. A late 2xx does not change the provider’s record of a timed-out attempt, so the provider may still send the event again.
Repeated requests show that the provider did not record a successful delivery under its rules; they alone cannot establish a provider defect. Compare the provider’s attempt history with receiver logs to determine whether the provider retried after a recorded failure, or whether the receiver produced the timeout or error.
Keep the request path short. Stripe advises webhook receivers to return a 2xx response before performing complex work, such as updating accounting systems. A receiver can validate and accept the event, then put the work in a queue for a background worker to pick up. The receiver can return 2xx once it accepts responsibility for processing the event. The queue lets another worker handle slower tasks without keeping the provider’s HTTP request open.
A 2xx acknowledges receipt; it does not prove that later processing succeeded. Monitor the background worker and its failures separately, so a fast acknowledgment does not hide an event that the receiver accepted but failed to process.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com