Utkarsh Jain
09/09/2025, 5:32 AMPermissionError: [Errno 13] Permission denied: '.env'
, this is not coming from a flow but the prefect run itself, here is the stack trace:
Traceback (most recent call last): │
│ File "<frozen runpy>", line 198, in _run_module_as_main │
│ File "<frozen runpy>", line 88, in _run_code │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/prefect/__main__.py", line 1, in <module> │
│ from prefect.cli import app │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/prefect/cli/__init__.py", line 2, in <module> │
│ from prefect.cli.root import app │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/prefect/cli/root.py", line 15, in <module> │
│ import prefect.context │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/prefect/context.py", line 950, in <module> │
│ GLOBAL_SETTINGS_CONTEXT: SettingsContext = root_settings_context() │
│ ^^^^^^^^^^^^^^^^^^^^^^^ │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/prefect/context.py", line 909, in root_settings_context │
│ profiles = prefect.settings.load_profiles() │
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/prefect/settings/profiles.py", line 307, in load_profiles │
│ current_settings = get_current_settings() │
│ ^^^^^^^^^^^^^^^^^^^^^^ │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/prefect/settings/context.py", line 21, in get_current_settings │
│ return Settings() │
│ ^^^^^^^^^^ │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/pydantic_settings/main.py", line 189, in __init__ │
│ **__pydantic_self__._settings_build_values( │
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/pydantic_settings/main.py", line 368, in _settings_build_values │
│ dotenv_settings = DotEnvSettingsSource( │
│ ^^^^^^^^^^^^^^^^^^^^^ │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/pydantic_settings/sources/providers/dotenv.py", line 51, in __init__ │
│ super().__init__( │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/pydantic_settings/sources/providers/env.py", line 58, in __init__ │
│ self.env_vars = self._load_env_vars() │
│ ^^^^^^^^^^^^^^^^^^^^^ │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/pydantic_settings/sources/providers/dotenv.py", line 63, in _load_en │
│ return self._read_env_files() │
│ ^^^^^^^^^^^^^^^^^^^^^^ │
│ File "/mnt/teams/gam-pm-team09/envs/quantops/master-el8-py312/.venv/lib/python3.12/site-packages/pydantic_settings/sources/providers/dotenv.py", line 100, in _read_e │
│ if env_path.is_file(): │
│ ^^^^^^^^^^^^^^^^^^ │
│ File "/opt/py312-gcc132/lib/python3.12/pathlib.py", line 892, in is_file │
│ return S_ISREG(self.stat().st_mode) │
│ ^^^^^^^^^^^ │
│ File "/opt/py312-gcc132/lib/python3.12/pathlib.py", line 840, in stat │
│ return os.stat(self, follow_symlinks=follow_symlinks) │
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ │
│ PermissionError: [Errno 13] Permission denied: '.env'
I dont have any .env file in directory and dont need oneMarvin
09/09/2025, 5:33 AMMarvin
09/09/2025, 5:40 AM.env
file in the current working directory.
- Your traceback shows the error occurs while pydantic checks Path('.env').is_file()
, which calls os.stat('.env')
. A PermissionError here means there is something named .env
in your current directory (a file, directory, or symlink) that your user cannot stat/access — even if you don’t intend to use it.
Why you see this even if you “don’t have a .env”:
- .env
is a hidden name; you won’t see it without listing hidden files.
- It could be a directory or a symlink with restrictive permissions (e.g., mode 000) or pointing somewhere you cannot access.
- pydantic-settings tries to check if it’s a file and trips over the permission error before it can decide to ignore it.
Quick ways to unblock:
1) Inspect what .env
actually is and its permissions
ls -lad .env
namei -l .env
stat .env
2) Fix or move it out of the way
- If it’s a file you don’t need:
mv .env .env.bak
- If it’s a directory with no execute bit (so you can’t stat it):
chmod u+x .env
- If it’s a file with no read bit:
chmod u+r .env
- If it’s a symlink, follow where it points (namei -l .env
) and fix permissions on the target or remove the symlink.
3) Run the Prefect CLI from a different working directory
- For example:
cd ~
prefect config view
This avoids the problematic .env
in your current project directory.
Important note:
- In Prefect 3.x there isn’t a setting/flag to disable .env
probing altogether; it’s part of the settings bootstrap done by pydantic-settings. We can consider improving error handling here, but for now the remedies above are the practical approaches.
If you can, please share:
- Output of ls -lad .env
and namei -l .env
- Your current working directory (pwd
)
- Prefect version (prefect version
)
Docs for reference:
- Settings and profiles in Prefect 3Utkarsh Jain
09/09/2025, 5:44 AMMarvin
09/09/2025, 5:44 AMMarvin
09/09/2025, 5:47 AM.env
in the previous CWD).
Recommended options:
1) Set workingDir in the Kubernetes work pool’s base job template
- Get the default template:
prefect work-pool get-default-base-job-template --type kubernetes > base.json
- Edit the container spec to add workingDir, e.g.:
{
"job_configuration": {
"job_manifest": {
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "prefect-job",
"image": "{{ image }}",
"imagePullPolicy": "{{ image_pull_policy }}",
"env": "{{ env }}",
"args": "{{ command }}",
"workingDir": "/home/prefect"
}
],
"restartPolicy": "Never",
"serviceAccountName": "{{ service_account_name }}"
}
}
}
},
...
}
}
- Apply it to your work pool:
prefect work-pool create "my-pool" --type kubernetes --base-job-template base.json --overwrite
2) Make workingDir configurable via job_variables (per-deployment)
- In your base job template, parameterize the directory:
"workingDir": "{{ working_dir }}"
- In your deployment call, set it:
flow.from_source("<https://github.com/org/repo>", entrypoint="flows/my_flow.py:flow").deploy(
name="my-deploy",
work_pool_name="my-pool",
job_variables={"working_dir": "/home/prefect"}
)
3) Set WORKDIR in your image or entrypoint
- If you own the container image, set WORKDIR /home/prefect
in the Dockerfile or add an entrypoint script that `cd`s before exec’ing the Prefect command.
Any of these ensures the container starts in a directory that doesn’t contain a .env
, so pydantic-settings won’t hit that PermissionError while probing for .env
.
References:
- Customize job variables
- Manage work pools
If you share your current work pool name and whether you prefer a pool-wide default or per-deployment override, I can sketch the exact JSON or deployment snippet.