Why Yanking a PyPI Release Is Safer Than Deleting It
When a PyPI wheel breaks, deleting it can break pins. Yanking keeps the file but tells pip to skip it for new installs. Learn how to yank with twine, verify pip’s resolver, and understand the trade‑offs.
01 Jul 2025, 18:10 UTC

Problem: The “Broken Wheel” Dilemma
Maintainers sometimes discover that a newly uploaded wheel contains a critical bug or a packaging error. The instinct is to delete the file from PyPI, but doing so can break reproducible builds and invalidate pins that other projects rely on. The question becomes: how do we signal to the ecosystem that a release should no longer be chosen for new installs while preserving the ability to satisfy existing constraints?
Thesis: Yanking is a Reversible, Non‑Destructive Safety Valve
PyPI’s PEP 592 introduces a yanked flag that marks a specific file as “not recommended for new installs.” This approach keeps the file available for backward‑compatibility, lets pip’s resolver skip it when possible, and provides a clear audit trail. Deleting a release removes the file entirely, which can break any project that has pinned that exact version.
How Pip Treats Yanked Releases
Modern pip (≥21.0) respects the yanked flag during dependency resolution:
- It will only install a yanked release if no non‑yanked version satisfies the requirement.
- It will still honour explicit version pins, even if the pinned release is yanked.
- Older pip versions that do not implement PEP 592 will ignore the flag and install the wheel normally.
Because pip can still install a yanked wheel via a direct URL, yanking is not a takedown mechanism; it is a recommendation system.
Practical Workflow: Using Twine to Yank a File
Twine, the recommended tool for publishing to PyPI, exposes a twine yank subcommand. The syntax is straightforward:
# After uploading a wheel
$ twine upload dist/mypkg-1.2.3-py3-none-any.whl
# Yank that specific file
$ twine yank mypkg mypkg-1.2.3-py3-none-any.whl
Alternatively, you can yank during the upload step:
$ twine upload --yank dist/mypkg-1.2.3-py3-none-any.whl
Key points:
- Permissions: You need an API token with the
uploadscope for the project. - Placeholder: Replace
mypkgwith your project name and the file path with the exact wheel you want to yank. - Risk: The file remains downloadable via
https://files.pythonhosted.org/packages/.../mypkg-1.2.3-py3-none-any.whl. - Verification: After yanking, run
pip install --dry-run mypkg==1.2.3in a clean virtual environment to confirm that pip skips the yanked release when newer versions exist.
Verifying Resolver Behavior
Use the following commands to double‑check:
# List available versions and see the yanked flag
$ pip index versions mypkg
# Dry‑run a pin to the yanked release
$ pip install --dry-run mypkg==1.2.3
If the resolver behaves as expected, the yanked release will be marked with yanked in the output and pip will only select it when no other suitable version is available.
Trade‑Offs and Limitations
- Older Pip: Users on pre‑PEP 592 pip will not see the yanked flag and may install the problematic wheel.
- Direct URL Downloads: The file can still be fetched directly, so yanking does not prevent malicious use if the wheel is compromised.
- Security Vulnerabilities: For critical security flaws, yanking alone is insufficient; a coordinated disclosure and a forced version constraint (e.g.,
mypkg<1.2.3) are recommended. - Reversibility: Yanking is reversible; you can un‑yank a file with
twine unyankif you later determine the issue was a false alarm.
Actionable Takeaways
- When you discover a broken wheel, yank it first rather than deleting.
- Run
pip install --dry-runin a fresh environment to confirm resolver behavior. - Publish a clear changelog entry explaining why the release was yanked and, if possible, provide a patch or a new version.
- For security‑critical issues, consider a coordinated disclosure and a strict version constraint in your
setup.cfgorpyproject.toml. - Document the yank in your project’s release notes so downstream users understand the rationale.
By following this workflow, maintainers preserve reproducibility, give pip a chance to avoid the problematic release, and keep the ecosystem informed.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.