How to Debug Webhook Timeouts and 500 Errors
A webhook is an HTTP request one service sends to another when an event occurs, such as a payment update or a…
A webhook is an HTTP notification that a provider sends to a URL on your service when something changes, such as a payment or account update. The provider’s retry window is the time or number of attempts it allows for automatically resending a notification after delivery fails. When that window ends, the provider stops automatic retries. What happens to the event itself depends on the provider: it might be discarded, remain available for manual resend, or be recoverable through an event-history or resource API.
A missed webhook can leave your records out of sync with the provider or stop a later action from happening. To recover, check whether the provider offers redelivery or event history, then compare your records with the provider’s current state. If neither path can restore the information, assess whether you can repair the affected record from other reliable evidence.
A provider sends a webhook request to your URL and checks whether it received a response that its rules count as successful. A connection failure or timeout can cause the provider to schedule another delivery attempt. An unsuccessful response can also trigger a retry. Providers set their own attempt limits and delays, and decide how long the retry period lasts.
When the limit expires, the provider stops scheduling automatic attempts and applies its own policy to the failed event. That policy may discard the notification, mark it failed while keeping it available for manual resend, or leave it accessible through another recovery mechanism. “Failed” therefore does not tell you by itself whether the event is still retrievable.
Provider policies illustrate the difference. Square’s webhook documentation describes automatic retries for up to 24 hours, after which it discards the notification; the same documentation points to its Events API for recovering and reconciling missed notifications. PayPal’s documentation describes up to 25 attempts over three days and says an unsuccessful delivery can still be resent manually from the Webhook Events dashboard. These are provider-specific rules, not a shared webhook standard.
For the event type you use, check whether automatic retries have stopped, whether the provider still keeps delivery or event data, and whether an API lets you check the current status of the thing the event describes. The retry cutoff answers only the first question.
The main risk is that your records no longer match the provider’s current information. If a payment-status notification never reaches your code, for example, your order record may continue to show an earlier status. A missed notification can also stop a later step from starting. The effect depends on what the event represented and whether another provider API exposes the relevant state.
An HTTP success response usually tells the provider that your endpoint accepted the delivery. It does not prove that later business processing finished. Adyen’s webhook guidance recommends storing the message before acknowledging it, then processing it separately. If your endpoint acknowledges a message but your code later fails to process it, the provider may consider delivery successful even though your records are incomplete.
Redelivery also creates a duplicate-processing risk. Your endpoint may process an event even if its acknowledgement never reaches the provider. If the provider later resends it, your code should recognize the repeated event and avoid repeating a business action. Square documents the use of event IDs to identify duplicate notifications. When event order matters, preserve and use the timestamps or sequence information the provider supplies.
Start by fixing the condition that caused delivery to fail. Check the provider’s delivery record for the response or connection outcome it logged, and confirm that your endpoint can accept new requests. If you resend events while the endpoint still fails, those deliveries will fail too. After service returns, account for a possible burst of queued deliveries. Adyen’s troubleshooting guidance warns that queued events can arrive close together after recovery.
Then choose the recovery path the provider supports:
A provider API does not necessarily preserve the same information as the original notification. For example, Plaid’s guidance on missed webhooks says its cited Monitor webhooks do not support on-demand replay after the retry window, while recommending API reconciliation and describing a beta endpoint that lists webhook events sent over the previous seven days. Check the rules for your specific provider and event type before relying on any recovery path.
If an event is obsolete, already reflected in your records, or impossible to recover, document that decision and close the incident. The fact that the provider stopped retrying does not show that your code handled the event or that you have nothing left to do.
Have your endpoint check and store each notification before acknowledging it. Then process the stored event separately. This keeps a later failure in your code from erasing the only copy your service received. Keep event IDs and timestamps so you can detect duplicates and check the order in which events arrived. Also monitor delivery failures and compare important local records with provider state, so a mismatch can surface before the provider’s recovery options expire.
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