modelscope / modelscope/modelscope_hub

Range resume corrupts files: a 200 response that serves the requested range is treated as a restart

Open
#50 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
14
Forks
8
Avg merge
1h
Merged PRs (30d)
13

Description

The ModelScope file endpoint answers a Range request with 200 OK instead of 206 Partial Content, even though it does serve only the requested slice:

curl -sL -o /dev/null -D -  
-H 'Range: bytes=1000000000-1000000099' 
'https://www.modelscope.cn/api/v1/models/Qwen/Qwen3-VL-8B-Instruct/repo?Revision=master&FilePath=model-00002-of-00004.safetensors'

Returned:

HTTP/1.1 200 OK
Server: nginx/1.24.0
Content-Length: 100
Accept-Ranges: bytes
Content-Range: bytes 1000000000-1000000099/4915962496

100 bytes requested, 100 bytes returned, correct Content-Range — the range is honoured. Only the status code is wrong. Per RFC 9110 §15.3.7 this should be 206.

And it may break the SDK

_download_with_resume decides whether a response is a resume from the status code alone.

is_resumed = resp.status_code == 206
...
mode = "ab" if is_resumed else "wb"
if not is_resumed:
    existing_size = 0

So on every resume is_resumed is False, and the .incomplete file is truncated (wb) — but the server is still sending from the requested offset, so mid-file bytes get written at offset 0. The result is a file that is both short and shifted. Nothing notices until the SHA-256 check rejects it, which then deletes the file and restarts from byte 0.

In one run over an unreliable link, /proc//io showed 30.9 GB written for a 17.5 GB model, with 6.1 GB retained.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the _download_with_resume entry point and inspect how response status and headers determine the write mode and existing offset. Reproduce the ModelScope response described in the issue, then verify that a resumed download is not truncated or shifted and that the completed file passes its SHA-256 check.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.