A single file over 50GB cannot be fetched through rustingface by an unmodified client #5

Open
opened 2026-09-02 12:03:29 +00:00 by grenade · 0 comments
Owner

Summary

huggingface_hub refuses to download a single file larger than
MAX_HTTP_DOWNLOAD_SIZE (50 GB, constants.py:39) over plain HTTP. Above
that it raises before any request is made:

The file is too large to be downloaded using the regular download method.
Use hf_transfer or hf_xet instead.

Both escape hatches are closed against rustingface:

  • hf_transfer sets Range: bytes=0-0 to learn the size and then chunks
    the download itself. It is deprecated upstream in favour of Xet, and is not
    used on the fleet.
  • hf_xet engages only when the server's response carries Xet file
    data (parse_xet_file_data_from_response, dispatched at
    file_download.py:1718). rustingface never emits those headers, by design
    (spec §8), so xet_file_data is None and the client falls to http_get —
    which is the path that refuses.

So this is not a rustingface bug and there is nothing to fix in the request
path. The failure happens client-side before rustingface is consulted. It is
recorded here because it is the one shape where "point HF_ENDPOINT at
rustingface and everything works" stops being true.

Scope today

Narrow. Repos shard well under the limit in practice — Qwen/Qwen3.8-Flash-Next
uses 3.3GB shards, and 5GB is a common ceiling. It bites only on a single
unsharded file above 50GB, such as a large GGUF quant or a monolithic
checkpoint.

The number moves the wrong way over time, though, which is the reason to
write it down: this is what would eventually force the Xet question, rather
than leaving it a preference.

Options, none of them urgent

  • Leave it. Document the boundary and let anyone who hits it shard or
    fetch directly. Costs nothing and stays honest.
  • Implement Xet. Removes the ceiling and follows where the Hub is going,
    but spec §8 rejected it deliberately: a Xet-backed fetch leaves the bucket
    unreadable without a Xet client, which forfeits the state portability the
    whole design rests on. That trade would need re-arguing, not assuming.
  • Support hf_transfer properly. Would work — it chunks below the limit
    — but it is deprecated upstream, so this is resource spent on a path with a
    known end date.

Filing as a known boundary rather than a defect. No action proposed.

## Summary `huggingface_hub` refuses to download a single file larger than `MAX_HTTP_DOWNLOAD_SIZE` (50 GB, `constants.py:39`) over plain HTTP. Above that it raises before any request is made: > The file is too large to be downloaded using the regular download method. > Use `hf_transfer` or `hf_xet` instead. Both escape hatches are closed against rustingface: - **`hf_transfer`** sets `Range: bytes=0-0` to learn the size and then chunks the download itself. It is deprecated upstream in favour of Xet, and is not used on the fleet. - **`hf_xet`** engages only when the *server's* response carries Xet file data (`parse_xet_file_data_from_response`, dispatched at `file_download.py:1718`). rustingface never emits those headers, by design (spec §8), so `xet_file_data is None` and the client falls to `http_get` — which is the path that refuses. So this is not a rustingface bug and there is nothing to fix in the request path. The failure happens client-side before rustingface is consulted. It is recorded here because it is the one shape where "point `HF_ENDPOINT` at rustingface and everything works" stops being true. ## Scope today Narrow. Repos shard well under the limit in practice — `Qwen/Qwen3.8-Flash-Next` uses 3.3GB shards, and 5GB is a common ceiling. It bites only on a single unsharded file above 50GB, such as a large GGUF quant or a monolithic checkpoint. The number moves the wrong way over time, though, which is the reason to write it down: this is what would eventually force the Xet question, rather than leaving it a preference. ## Options, none of them urgent - **Leave it.** Document the boundary and let anyone who hits it shard or fetch directly. Costs nothing and stays honest. - **Implement Xet.** Removes the ceiling and follows where the Hub is going, but spec §8 rejected it deliberately: a Xet-backed fetch leaves the bucket unreadable without a Xet client, which forfeits the state portability the whole design rests on. That trade would need re-arguing, not assuming. - **Support `hf_transfer` properly.** Would work — it chunks below the limit — but it is deprecated upstream, so this is resource spent on a path with a known end date. Filing as a known boundary rather than a defect. No action proposed.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: grenade/rustingface#5