Skip to content

[Download] Harden resume validation#4143

Open
anujbharambe wants to merge 1 commit intohuggingface:mainfrom
anujbharambe:bugfix/resume-recovery-4060
Open

[Download] Harden resume validation#4143
anujbharambe wants to merge 1 commit intohuggingface:mainfrom
anujbharambe:bugfix/resume-recovery-4060

Conversation

@anujbharambe
Copy link
Copy Markdown

@anujbharambe anujbharambe commented Apr 24, 2026

Summary

  • Persist resume metadata alongside .incomplete files to detect mismatches and restart safely.
  • Validate resume responses with If-Range and Content-Range before appending data.
  • Add regression coverage for resume metadata mismatch and updated http_get behavior.

Details

This change hardens resume behavior for large downloads by:

  • Writing a small resume state sidecar that stores ETag, expected size, and a normalized URL.
  • Rejecting resumes when metadata mismatches or the server returns an unexpected Content-Range.
  • Falling back to a clean restart when resume safety checks fail.

This addresses unreliable resume cases and prevents silent corruption due to appending the wrong byte ranges.

Reviewers

@kripper

Closes #4060


Note

Medium Risk
Changes core download/resume behavior by introducing new validation paths (ETag/Content-Range checks) and restart fallbacks, which could affect large-file downloads and retry semantics if edge cases are mishandled.

Overview
Hardens resumable downloads to prevent silent corruption. http_get now supports an optional etag, sends it via If-Range on resume, handles 416 Range Not Satisfiable by restarting cleanly, and validates 206 responses by checking Content-Range matches the requested resume position (otherwise restart from scratch).

Persists and validates resume state for .incomplete files. _download_to_tmp_and_move now writes a sidecar .metadata file (etag/expected size/normalized URL) and deletes/restarts when metadata or size is inconsistent, cleaning up the metadata file on completion or when force_download=True. Tests add coverage for metadata mismatch resets and update http_get retry mocks to include status_code/Content-Range behavior.

Reviewed by Cursor Bugbot for commit 299fda4. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread src/huggingface_hub/file_download.py Outdated
Comment thread src/huggingface_hub/file_download.py Outdated
Comment thread src/huggingface_hub/file_download.py Outdated
Comment thread src/huggingface_hub/file_download.py
Comment thread src/huggingface_hub/file_download.py Outdated
Comment thread src/huggingface_hub/file_download.py
Comment thread src/huggingface_hub/file_download.py
Comment thread src/huggingface_hub/file_download.py Outdated
Comment thread src/huggingface_hub/file_download.py
@anujbharambe anujbharambe force-pushed the bugfix/resume-recovery-4060 branch 2 times, most recently from 9ed38a2 to 35a40b2 Compare April 24, 2026 22:04
Comment thread src/huggingface_hub/file_download.py
Comment thread src/huggingface_hub/file_download.py
This commit hardens the download resumption logic to prevent data corruption and improve reliability:
- Implements symmetric validation for ETag and expected_size in resume metadata.
- Fixes unreachable 416 (Range Not Satisfiable) handler by checking status before raising.
- Ensures etag/Range parameters are correctly forwarded during connection-error retries.
- Fixes Content-Range validation to account for initial Range offsets and enforces strict validation.
- Always persists resume metadata sidecars from the first download attempt.
- Ensures metadata sidecars are cleared when force_download=True, even if incomplete file is missing.
- Removes redundant ETag formatting logic as normalization is handled upstream.
- Removes error-prone sentinel values ('none') in favor of unambiguous empty strings.
- Adds comprehensive tests for Range-based resumes and metadata integrity.
@anujbharambe anujbharambe force-pushed the bugfix/resume-recovery-4060 branch from 35a40b2 to 299fda4 Compare April 24, 2026 22:23
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 299fda4. Configure here.

Comment thread src/huggingface_hub/file_download.py
@anujbharambe
Copy link
Copy Markdown
Author

Hey @kripper @Wauplin - this PR is ready for review.

All Cursor Bugbot comments have been addressed and resolved. The remaining open Bugbot findings are low-severity style observations (dead code branch, duplicate regex), not correctness issues.

Summary of what this does:
--> Persists a '.metadata' sidecar alongside '.incomplete' files to detect stale resumes (changed etag/size/url) and restart safely
--> Adds 'If-Range' header and 'Content-Range' validation in 'http-get'
--> Handles 416 (Range Not Satisfiable) gracefully instead of crashing
--> Adds test coverage for metadata mismatch and http_get retry behavior

Closes #4060

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.

Unreliable resume support and lack of partial corruption recovery in large file downloads

2 participants