Hugging Face download stuck at 0 KB/s? Turn off Xet
The short answer
My Hugging Face downloads stalled twice in the Xet transfer client (hf_xet, which huggingface_hub uses on its own when it is installed). A 7.3 GB model stopped at 2.75 GB, then sat at 0 KB/s from the start on the retry; a 24.6 GB GGUF stopped at 10.8 GB. No error either time. Running the same hf download with HF_HUB_DISABLE_XET=1 went over plain HTTP and finished the 7.3 GB model at about 4 to 12 MB/s.
Turning Xet off starts the file again from zero. For the 24.6 GB file I kept the 10.8 GB partial instead, fetched the missing bytes with HTTP range requests (curl -r), and checked the sha256 against the file's lfs.oid from the Hub API. It matched.
What I saw
No error message. The download just stopped moving.
Speed: 0 KB/s.
The .incomplete file in the download folder stopped growing.
YuE2-3B (7.3 GB): stopped at 2.75 GB. After a restart with Xet still on: 0 KB/s from the start, and the partial file was thrown away instead of resumed.
Drama 3 GGUF (24.6 GB): stopped at 10.8 GB.Where I hit it
- Machine
- Linux desktop PC
- Library
- huggingface_hub 0.36.2 with hf_xet installed (I didn't note the hf_xet version)
- Command
- hf download <repo>
- First stall (2026-10-11)
- YuE2-3B, 7.3 GB
- Second stall (2026-10-14)
- Drama 3 GGUF, one 24.6 GB file
- Connection
- about 11 MB/s total, even split over 8 connections
Why it happens
When hf_xet is installed, huggingface_hub uses it automatically for downloads (environment variables docs). hf_xet pulls files from Xet, the storage backend the Hub moved to from Git LFS, which stores files as deduplicated chunks (Xet storage docs). HF_HUB_DISABLE_XET turns hf_xet off even when it is installed, so the download goes through a regular HTTP request for the whole file instead.
What my log shows: the Xet path stalled twice, on 2026-10-11 and 2026-10-14, with no error. Restarting with Xet still on did not resume; it started over, sat at 0 KB/s, and dropped the partial file. The plain HTTP path on the same line finished. Restarting with HF_HUB_DISABLE_XET=1 also starts the file from zero, which is why I resumed the 24.6 GB file by hand.
My guess, not something I proved: the problem was between my connection and Xet's transfer servers, since plain HTTP on the same line worked. I didn't keep hf_xet's logs (they go under ~/.cache/huggingface/xet/logs/ by default), so I can't say what failed inside it. Other people have reported the same symptom, for example xet-core: Downloads Stall when hf-xet is Enabled, where HF_HUB_DISABLE_XET=1 also worked. That issue was closed in July after a fix release; my stalls came in October, and I didn't record which hf_xet version I had.
The fix
- Check that it is stuck, not slow. With
--local-dirthe partial file sits in<dir>/.cache/huggingface/download/; without it, in the cache under~/.cache/huggingface/hub/models--<org>--<name>/blobs/. If the.incompletefile hasn't grown for more than 15 seconds, I treat it as a Xet stall.watch -n 15 'ls -l <dir>/.cache/huggingface/download/' - Stop it with Ctrl+C and run the same download with Xet turned off. huggingface_hub reads environment variables when it is imported, so set the variable on the command line or in your launcher script, not halfway through a Python session. This throws away the partial file and starts again from zero; for the 7.3 GB model that was fine.
HF_HUB_DISABLE_XET=1 hf download <repo> --local-dir <dir> - If a big file already got far, don't rerun
hf downloadon it (that discards the partial). Get the file's exact size and sha256 from the Hub API instead:lfs.sizeandlfs.oidin the repo tree listing. Add-H "Authorization: Bearer $HF_TOKEN"for gated or private repos.curl -s https://huggingface.co/api/models/<repo>/tree/main \ | jq '.[] | select(.path=="<file>") | .lfs' - Fetch the missing bytes with a range request starting at the partial file's size. The
resolveURL redirects to a download server that answers range requests, socurl -L -rworks.--speed-limit 100000 --speed-time 60makes curl quit if it drops under 100000 bytes/s for 60 seconds, so a stall turns into an exit instead of a hang; if that happens, run it again withstartmoved forward by the size ofrest.part. I split the rest into 8 ranges in parallel, but my line stayed at about 11 MB/s total, so one range is enough.size=<lfs.size> start=$(stat -c %s <partial>.incomplete) curl -sSL --retry 5 --speed-limit 100000 --speed-time 60 \ -r "$start-$((size - 1))" \ "https://huggingface.co/<repo>/resolve/main/<file>" >> rest.part - Append the new bytes, then check the size and the sha256 against the Hub before you use the file. Only rename it when both match. This works only if the partial file has no gaps. Mine had none, and the hash proved it. hf_xet is built to write to disk in parallel (see
HF_XET_RECONSTRUCT_WRITE_SEQUENTIALLYin the docs), so I wouldn't count on every stalled partial being filled from the front. If the hash doesn't match, download the file again with Xet off.cat rest.part >> <partial>.incomplete stat -c %s <partial>.incomplete # must equal lfs.size sha256sum <partial>.incomplete # must equal lfs.oid mv <partial>.incomplete <dir>/<file> - To keep Xet off for one tool, export the variable in that tool's launcher script. I did this in the script that downloads my music models.
export HF_HUB_DISABLE_XET=1
How I checked it worked
- YuE2-3B (7.3 GB) finished with
HF_HUB_DISABLE_XET=1at about 4 to 12 MB/s on 2026-10-11. - Drama 3 GGUF (24.6 GB): after appending the range-request parts to the 10.8 GB partial, the size matched and the sha256 matched the Hub API's
lfs.oidon 2026-10-14. - Splitting the rest into 8 parallel connections gave about 11 MB/s total, no faster, so the line itself was the limit for that part (my reading).
Sources
- huggingface_hub docs: Environment variables, HF_HUB_DISABLE_XET
- The same page for huggingface_hub v0.36.2, the version I had
- Hugging Face Hub docs: Xet, our storage backend
- Hugging Face Hub docs: Using Xet storage (hf_xet, environment variables, logs)
- Hugging Face Hub API endpoints (OpenAPI reference, includes the repo tree listing)
- huggingface/xet-core issue: Downloads Stall when hf-xet is Enabled