Skip to content

fix: retry uploads on a 408 request_timeout response (#605) - #608

Closed
ffumero2003 wants to merge 1 commit into
masterfrom
codex/fix-605-request-timeout-retry
Closed

ffumero2003 wants to merge 1 commit into
masterfrom
codex/fix-605-request-timeout-retry

Conversation

@ffumero2003

@ffumero2003 ffumero2003 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Problem

An upload that receives a 408 request_timeout from B2 raises UnknownError to
the caller after a single attempt — no retry, no fresh upload URL — unlike the
401 (expired token), 500, and 503 cases, which all retry. Backblaze's Integration
Checklist lists 408 as a recognized upload failure after which the client should
get a new upload URL and retry.

Root cause

interpret_b2_error has an explicit branch for every status it treats specially
(400s, 401, 403, 409, 416, 429, 500–599) but none for 408, so a 408 falls through
to return UnknownError(...). UnknownError is a bare B2SimpleError and does
not mix in TransientErrorMixin, so should_retry_upload() is False — and
UploadManager's retry loop gives up immediately.

Fix

Map 408 to a retryable exception, mirroring how 500/503 map to ServiceError:

  • Add RequestTimeout(TransientErrorMixin, B2Error) (so should_retry_upload()
    and should_retry_http() are both True).
  • Add elif status == 408: return RequestTimeout(...) to interpret_b2_error,
    before the 429 branch.

Scope is limited to the exception mapping; UploadManager and the transport
retry wiring are unchanged — the retry gate was already correct, it just never
received a retryable exception for 408.

Testing

  • New unit test asserting interpret_b2_error(408, ...) returns a RequestTimeout
    whose should_retry_upload() and should_retry_http() are both True
    (red before the change, green after).
  • Full unit suite passes across all API versions (nox -s unit, apiver v0–v3).

Fixes #605.

@sophiecarreras sophiecarreras left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is superseded by #618, which carries the same change (byte-identical diff for the code, tests and changelog fragment). Closing this one avoids two PRs adding the same fragment and test. Please close whichever you want to drop; I suggest keeping #618.

@ffumero2003

Copy link
Copy Markdown
Contributor Author

Superseded by #618, which merged to master with the same fix plus the review nits (safe Retry-After parsing / v3 export etc.). The change here is already on master, so closing this duplicate.

@ffumero2003 ffumero2003 closed this Oct 1, 2026
@ffumero2003
ffumero2003 deleted the codex/fix-605-request-timeout-retry branch October 1, 2026 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A 408 (request_timeout) response is never retried on upload, unlike 401/500/503

2 participants