You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Retried requests leave their request timeout armed since 22.6.0 (process stays alive for the full timeout) #2897
Since 22.6.0, a request that gets retried leaves the failed attempt's timeout timer armed until it fires. The call itself succeeds and returns the right result, but with the default timeout of 80s, a short-lived process that hit one retry stays alive for 80 seconds after its work is done. Deno's test sanitizer also fails tests on the pending timer.
Root cause: since #2815 (the fix for #2814), FetchHttpClient keeps the timeout armed after the headers arrive so it also bounds the body read, and only toJSON() or toStream() calls requestTimeout.release(). When RequestSender decides to retry (a 5xx, a 409, stripe-should-retry: true), it passes the response straight to retryRequest without reading its body, so that attempt's timer is never released:
Create a client with Stripe.createFetchHttpClient() over a fetch that returns a 500 and then a 200, with maxNetworkRetries: 1 and timeout: 5000 (full script under Code snippets).
Call stripe.customers.retrieve('cus_1').
The call resolves with the customer after one retry, but one timer with the timeout delay is still pending, and the process does not exit until it fires (about 5s later).
Without the 500 (no retry), no timer is left and the process exits at once.
Expected behavior
A response the SDK discards in order to retry releases its timeout, so the process exits as soon as the call settles, as it did through 22.5.0.
{"arm":"control","calls":1,"customer":"cus_1","leaked_request_timeouts":0}
process exited 5ms after start
{"arm":"retry","calls":2,"customer":"cus_1","leaked_request_timeouts":1}
process exited 5003ms after start
Same retry-arm result across releases:
stripe-node
retry arm
18.5.0, 19.0.0, 21.0.1, 22.2.2, 22.3.2, 22.5.0
no leaked timer, exits after the retry backoff
22.6.0, 22.6.2, 23.0.0, 23.1.0-beta.1
1 leaked timer, exits after timeout
22.6.0 is the release that shipped #2815. One possible fix is to release the timeout (or cancel the body) on the response before retrying it. Reading it through toJSON() without awaiting it also releases the timer without making the retry wait on a stalled body.
Hi @KevinDeLaTorre ! Thanks for raising this! I actually just found and put up a fix for this last night: #2895 (amongst other things). I'll try and verify it with your steps to reproduce; if you have a moment and a reproducable test project, could you try installing from this branch to see if it resolves ihe issue?
@jar-stripe Thanks for the quick fix! I built the branch and ran the repro from the issue against it and against 23.0.0:
23.0.0, retry arm: leaked_request_timeouts 1, process exited 5002ms after start #2895, retry arm: leaked_request_timeouts 0, process exited 506ms after start
control arm on both: 0 leaked, exited in 3ms
So the retried attempt's timer is released and the process exits right after the retry backoff, same as 22.5.0. Looks good from my side.
@KevinDeLaTorre fantastic, thank you for confirming! The branch with the fix has been merged and this will go out with this month's release. I'll leave this issue open until the release is out.
Activity
jar-stripe commentedon Oct 15, 2026
Hi @KevinDeLaTorre ! Thanks for raising this! I actually just found and put up a fix for this last night: #2895 (amongst other things). I'll try and verify it with your steps to reproduce; if you have a moment and a reproducable test project, could you try installing from this branch to see if it resolves ihe issue?
KevinDeLaTorre commentedon Oct 15, 2026
@jar-stripe Thanks for the quick fix! I built the branch and ran the repro from the issue against it and against 23.0.0:
23.0.0, retry arm: leaked_request_timeouts 1, process exited 5002ms after start
#2895, retry arm: leaked_request_timeouts 0, process exited 506ms after start
control arm on both: 0 leaked, exited in 3ms
So the retried attempt's timer is released and the process exits right after the retry backoff, same as 22.5.0. Looks good from my side.
jar-stripe commentedon Oct 19, 2026
@KevinDeLaTorre fantastic, thank you for confirming! The branch with the fix has been merged and this will go out with this month's release. I'll leave this issue open until the release is out.