cd /news/developer-tools/your-wheel-can-be-a-valid-zip-and-st… · home › topics › developer-tools › article
[ARTICLE · art-144742] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Your wheel can be a valid zip and still break installers. I built a checker for that.

A developer built zipgate, an MIT-licensed Python tool that hand-parses ZIP local file headers and central directory entries to detect malformed ZIP64 extra fields (0x0001) that Python's zipfile silently tolerates but stricter installers reject. The tool was validated against two real incidents: a 5.8 GiB PyTorch ROCm nightly wheel that failed under uv with "zip64 extended information field was too long" (astral-sh/uv#19440), and wheel 0.47.0 silently writing illegal ZIP64 structures into retagged wheels (pypa/wheel#692), which zipgate flags as SPURIOUS_ZIP64_LOCAL while the 0.48.0 output passes. It ships with eight tests and byte-level fixtures for both incident classes, and exits 0 for valid, 1 for invalid, and 2 for unreadable wheels.

by read1 min views1 publishedOct 4, 2026

A 5.8 GiB PyTorch ROCm nightly wheel failed to install under uv with zip64 extended information field was too long (astral-sh/uv#19440). Separately, wheel tags in wheel 0.47.0 was silently writing illegal ZIP64 structures into retagged wheels (pypa/wheel#692).

Both are the same class of problem: the ZIP64 extra field (0x0001) in the file doesn't match what APPNOTE 4.5.3 requires. Python's zipfile reads these files fine — it silently tolerates the malformation — and then a stricter installer falls over.

I parse local file headers and central directory entries by hand (not trusting zipfile) and validate:

0xFFFFFFFF. This is exactly what wheel 0.47.0 did: an 8-byte ZIP64 extra in headers whose 32-bit sizes were perfectly fine. I reproduced the wheel#692 MRE (lowering zipfile.ZIP64_LIMIT to force the ZIP64 path on small files, as the issue suggests), built a wheel, and retagged it:

artifact zipgate verdict
original wheel VALID
retagged with wheel 0.47.0 INVALID —SPURIOUS_ZIP64_LOCAL on two entries
retagged with wheel 0.48.0 VALID

The 0.47.0 output trips the exact rule the issue describes; 0.48.0 is clean.

pip install zipgate
zipgate dist/*.whl

Exit 0 = all valid, 1 = at least one invalid, 2 = unreadable. Eight tests, byte-level fixtures for both incident classes.

Repo: hahahahahahahahah6/zipgate (MIT).

If you ship wheels — especially big ones, or retagged ones — it's worth one command before upload.

── more in #developer-tools 4 stories · sorted by recency
── more on @zipgate 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/your-wheel-can-be-a-…] indexed:0 read:1min 2026-10-04 · —