I hit this wall on a Windows-8.1 laptop running Python 3.4: every time I tried to upgrade pip
(or install anything) the installer froze with a nasty WinError 5
. Below is the small utility I wrote to fight back, a plain-English autopsy of the error, and the handful of habits that now keep my machines trouble-free.
Whenever I try to install a new package or even just upgrade pip
I hit the same roadblock. On my Windows 8.1 machine running Python 3.4, pip
insists I lack the required admin rights, even though I’m signed in with an administrator account. It’s blocking my progress, so any advice on clearing this permission hurdle would be a huge help.
Error Message
Installing collected packages: pip
Found existing installation: pip 6.0.8
Uninstalling pip-6.0.8:
Removing file or directory c:\program files (x86)\python\python34\lib\site-packages\pip-6.0.8.dist-info\description.rst
Cleaning up...
Exception:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python\Python34\lib\shutil.py", line 523, in move
os.rename(src, real_dst)
PermissionError: [WinError 5] Access is denied: 'c:\\program files (x86)\\python\\python34\\lib\\site-packages\\pip-6.0.8.dist-info\\description.rst' -> 'C:\\Users\\User\\AppData\\Local\\Temp\\pip-uze_sc4k-uninstall\\program files (x86)\\python\\python34\\lib\\site-packages\\pip-6.0.8.dist-info\\description.rst'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python\Python34\lib\site-packages\pip\basecommand.py", line 232, in main
status = self.run(options, args)
File "C:\Program Files (x86)\Python\Python34\lib\site-packages\pip\commands\install.py", line 347, in run
root=options.root_path,
File "C:\Program Files (x86)\Python\Python34\lib\site-packages\pip\req\req_set.py", line 543, in install
requirement.uninstall(auto_confirm=True)
File "C:\Program Files (x86)\Python\Python34\lib\site-packages\pip\req\req_install.py", line 667, in uninstall
paths_to_remove.remove(auto_confirm)
File "C:\Program Files (x86)\Python\Python34\lib\site-packages\pip\req\req_uninstall.py", line 126, in remove
renames(path, new_path)
File "C:\Program Files (x86)\Python\Python34\lib\site-packages\pip\utils\__init__.py", line 316, in renames
shutil.move(old, new)
File "C:\Program Files (x86)\Python\Python34\lib\shutil.py", line 536, in move
os.unlink(src)
PermissionError: [WinError 5] Access is denied: 'c:\\program files (x86)\\python\\python34\\lib\\site-packages\\pip-6.0.8.dist-info\\description.rst'
Change Code
"""
pip_fix.py
Run python pip_fix.py requests
and watch it install/upgrade a package. If the regular call trips over
WinError 5 the script retries instantly with the safer --user flag.
"""
import ctypes
import subprocess
import sys
from pathlib import Path
def is_admin() -> bool:
try:
return ctypes.windll.shell32.IsUserAnAdmin() # UAC check
except Exception:
return False
def install(package: str) -> None:
cmd = [sys.executable, "-m", "pip", "install", "--upgrade", package]
try:
subprocess.check_call(cmd)
print(f" {package} installed system-wide.")
except subprocess.CalledProcessError as exc:
if "WinError 5" in str(exc):
print("
Hit PermissionError [WinError 5]. Retrying with --user…")
subprocess.check_call(cmd + ["--user"])
print(f" {package} installed in"
f" {Path.home() / 'AppData' / 'Roaming' / 'Python'}")
else:
raise
if __name__ == "__main__":
if len(sys.argv) < 2:
sys.exit("Usage: python pip_fix.py <package>")
if not is_admin():
print("
You are **not** running an elevated command prompt.")
install(sys.argv[1])
It takes less time to paste this file than to Google the error every few weeks. Now I type:
python pip_fix.py pandas
and move on with my day.
Run Output
PermissionError: [WinError 5] Access is denied:
'c:\\program files (x86)\\python\\python34\\lib\\site-packages\\…'
- Root cause – Anything beneath C:\Program Files is protected by User-Account Control. Even if my Windows login is in the Administrators group, each new process starts as a regular user until I explicitly “Run as administrator”. When
pip
tries to delete or rename its own metadata (…\pip-x.y.z.dist-info
), the filesystem slams the door and Python bubbles that up as aPermissionError
. - In human words – PIP is poking a file that my current security token can’t touch. Windows refuses, Python screams, and the install dies halfway.
Four Quick Cures
Drop into an elevated prompt
- Press ⊞ Win → type cmd
- Right-click → Run as administrator
- Re-run the failing
pip install --upgrade <pkg>
Stay safe with --use
Python -m pip install --upgrade --user <package>
PIP stores the files in %APPDATA%\Python\PythonXY\site-packages
, avoiding admin turf completely.
Work inside a virtual environment
Py -3.12 -m venv .venv
.venv\Scripts\activate
pip install <package list>
A venv is just another folder I own, so no permissions drama.
Keep a portable Python outside Program Files
Grab the ZIP/embeddable build from python.org, unzip it toC:\Users\<you>\Tools\Python\
, and point your PATH there.
System folders stay untouched; upgrades are drag-and-drop.
Hands on Practice
Scenario | Command prompt | Expected result |
---|---|---|
A · Normal user | python pip_fix.py pip | Script prints WinError 5, then retries with --user and succeeds |
B · Inside an activated venv | python pip_fix.py pip | Succeeds immediately (the venv is writable) |
C · Elevated cmd | python pip_fix.py pip | Succeeds immediately, upgrading the system pip |
Check where each install lands site-packages
will differ every time.
Why This Pattern Sticks
- One-liner convenience –
python pip_fix.py <pkg>
means no flag-salad to remember. - Built-in guardrails – The fallback spares me accidental system-wide changes when I’m not elevated.
- Debug confidence – Seeing
WinError 5
now makes sense; I fix it instead of spiralling into Stack Overflow.
Final Thought
I used to dread that red wall of text. Writing a 30-line helper flipped the script: I haven’t seen Access is denied
in months, and if it ever reappears I know exactly who’s to blame me, running the wrong prompt. Steal this file, tweak it, share it with the next person who complains, and spend your brain-cells on actual code instead of permission puzzles.