Permission error when accessing pip.exe in virtual environment (Python 3.10 on Windows)

I get this error (bash terminal) when trying to run the “pip install -e .” command which accesses the pip.exe under Scripts in the venv directory. I am aware that poetry and pyproject.toml is the more modern approach for dependency management, but this is not the way we currently do it in production and hence I need to stick to the with pip route.

When looking for obvious potential problems ( “whoami” and checking permissions when running “ls -la” in the venv directory), like who owns that executable, I found that I was both the creator and owner and have execution rights to pip.exe, and it was me running the terminal.

What should be noted is that I never got this error before, and I am not sure what has changed. I suspect it might be because I am using multiple different versions of Python.

I got this error both after installing my desired python versions (3.10.11 and 3.11.4) first from the Python website, then uninstalled (thinking this could be the problem), then both from the Microsoft Store, but the error persisted.

After activating the environment, try using python -m pip instead of pip. If python -m pip works, there’s a problem with the “pip.exe” launcher.

Hi Eryk :slight_smile: Thanks for your reply. I tried the route you suggested, and it worked. But does this not mean I am not actually using the pip.exe that is present in venv/Scripts? Can you suggest anything to further troubleshoot this? Thanks :slight_smile:

Based on the error text, it looks like the right “pip.exe” launcher is being executed, but there’s a problem with it. To test whether it works normally, run

"C:\Users\<username>\<project dir>\venv\Scripts\pip.exe" -V

in a normal command prompt (i.e. the CMD shell, not bash). Replace <username> and <project dir> with the real directory names.

I got “Access is denied.” in CMD. Is there something specific I can look for in checking the permissions of the .exe? Or is it perhaps broken in some other way?

Check the path of “python.exe” that’s embedded in “pip.exe”. Here’s a basic script that does the latter:

import sys
d = open(sys.argv[1], 'rb').read()[-4096:]
i = d.rfind(b'PK\x05\x06')
i0 = d.rfind(b'#!', 0, i) + 2
i1 = d.find(b'\n', i0)
p = d[i0:i1].strip(b'"').decode()

Pass the quoted path to “pip.exe” on the command line. For example: python "C:\Users\<username>\<project dir>\venv\Scripts\pip.exe".


The above assumes that “Access is denied” was from the launcher, in which case the full error would look like “Fatal error in launcher: … : Access is denied.”. If you didn’t see “Fatal error in launcher”, then the issue is just that the current user isn’t allowed to execute the “pip.exe” launcher. Run icacls "path\to\pip.exe" to dump the file’s access control list.

Thank you! I tried to run the script, but I got “permission denied” again - not sure if I did it right though, but I used python “C:\Users<username><project dir>\venv\Scripts\pip.exe” where includes to code you provided. When I run I get this output:

I presume the screenshot is the output from running icacls on “pip.exe”. It has the expected access control list for a file created within a user profile directory, so that’s not the problem.

Please run python "path\to\" "path\to\pip.exe" from a normal command prompt – not from bash and without activating the virtual environment, and where “” is the little script that I posted that shows the path of “python.exe” that’s embedded inside of “pip.exe”.

Hi Eryk :slight_smile: When you say “path\to\pip.exe” do you mean the path to pip globally or just in this virtual environment? I think that’s maybe where I missed you

I meant the one in the virtual environment. “pip.exe” is a launcher that has the path to “python.exe” and a little “” script appended to it. It spawns “python.exe” and passes its own path on the command line. Python’s zipimport module handles importing the embedded script from “pip.exe”. I just want to be sure that “pip.exe” contains the correct path to “python.exe” in the virtual environment’s “Scripts” directory, so that we know it’s trying to spawn the right executable.

BTW, “python.exe” in the virtual environment is also a launcher. It reads the “pyvenv.cfg” file in the parent directory in order to find and spawn the real “python.exe”. Overall you have “pip.exe” (launcher) -> “python.exe” (launcher) -> “python.exe” (real).

Hi there Eryk :slight_smile: Sorry for the delayed response, I must be doing something wrong because I cannot get it to work, what you’re asking me to do. Please have a look at this terminal output?