Summary
The request scheduler currently retries on 5xx, 404, 415 and 412, but not on 429 Too Many Requests. We'd like to propose adding 429 to the retryable HTTP statuses, and — as a softer, secondary ask — honoring a Retry-After header when the server sends one.
Motivation
We hit this with an origin that lazily prepares (transcodes) media segments. When several clients request the same not-yet-prepared segment at once, the origin serves the first request and answers the rest with 429 Too Many Requests + Retry-After: <seconds>, expecting the client to retry shortly. This is a fairly standard pattern for rate-limited or lazily-generated assets.
With the current behavior a 429 surfaces as a fatal NetworkError instead of being retried, so playback fails for every client but the first — even though a short retry would succeed.
Current behavior
shouldRetry in src/core/fetchers/utils/schedule_request.ts retries an HTTP error only when:
error.status >= 500 || error.status === 404 || error.status === 415 || error.status === 412
So 429 is treated as a non-retryable, fatal error (verified on v4.4.1). The retry delay is a pure exponential backoff (baseDelay * 2^(n-1) + fuzz); no response header is consulted.
Proposed change
-
(primary) Include 429 in the retryable set. This looks consistent with how 412 and 415 were added for specific delivery scenarios, and 429 is a standard "retry later" status. The existing backoff already covers the common case, so this is a small, low-risk change. We'd be happy to open a PR for this if you're open to it.
-
(optional) Honor Retry-After when present. When a retryable response carries Retry-After, use it as the next delay (capped to maxDelay) instead of the computed backoff. We understand this is a larger change to the delay model, and that a custom segmentLoader can already read the header and drive retries via canRetry. We raise it because respecting Retry-After is the spec-aligned behavior for 429/503, and having it built in would spare every consumer from reimplementing it for a common origin behavior.
Alternatives considered
A custom segmentLoader that reads Retry-After and retries works, but pushes a standard HTTP behavior onto each application. We searched existing issues/PRs and didn't find anything tracking 429 / Retry-After; pointers welcome if we missed one.
Environment
Summary
The request scheduler currently retries on
5xx,404,415and412, but not on429 Too Many Requests. We'd like to propose adding429to the retryable HTTP statuses, and — as a softer, secondary ask — honoring aRetry-Afterheader when the server sends one.Motivation
We hit this with an origin that lazily prepares (transcodes) media segments. When several clients request the same not-yet-prepared segment at once, the origin serves the first request and answers the rest with
429 Too Many Requests+Retry-After: <seconds>, expecting the client to retry shortly. This is a fairly standard pattern for rate-limited or lazily-generated assets.With the current behavior a
429surfaces as a fatalNetworkErrorinstead of being retried, so playback fails for every client but the first — even though a short retry would succeed.Current behavior
shouldRetryinsrc/core/fetchers/utils/schedule_request.tsretries an HTTP error only when:So
429is treated as a non-retryable, fatal error (verified on v4.4.1). The retry delay is a pure exponential backoff (baseDelay * 2^(n-1)+ fuzz); no response header is consulted.Proposed change
(primary) Include
429in the retryable set. This looks consistent with how412and415were added for specific delivery scenarios, and429is a standard "retry later" status. The existing backoff already covers the common case, so this is a small, low-risk change. We'd be happy to open a PR for this if you're open to it.(optional) Honor
Retry-Afterwhen present. When a retryable response carriesRetry-After, use it as the next delay (capped tomaxDelay) instead of the computed backoff. We understand this is a larger change to the delay model, and that a customsegmentLoadercan already read the header and drive retries viacanRetry. We raise it because respectingRetry-Afteris the spec-aligned behavior for429/503, and having it built in would spare every consumer from reimplementing it for a common origin behavior.Alternatives considered
A custom
segmentLoaderthat readsRetry-Afterand retries works, but pushes a standard HTTP behavior onto each application. We searched existing issues/PRs and didn't find anything tracking429/Retry-After; pointers welcome if we missed one.Environment
4.4.1