<@ULVA73B9P> I have set the PREFECT_LOCAL_STORAGE_...
# ask-marvin
b
@Marvin I have set the PREFECT_LOCAL_STORAGE_PATH env var to /home/prefect/cache/storage but I'm getting errors about not being able to write to /home/prefect/.prefect/storage/ -- why is prefect still trying to write to the default storage path?
m
thought for 140.5 seconds
Short answer: Prefect is writing to ~/.prefect/storage because the process that’s running your flow doesn’t “see” your
PREFECT_LOCAL_STORAGE_PATH
at startup, so it falls back to
{PREFECT_HOME}/storage
(default
{home}/.prefect/storage
). In Prefect 3.x: - The local result store defaults to
{PREFECT_HOME}/storage
. -
PREFECT_LOCAL_STORAGE_PATH
overrides that, but only if the environment variable is present in the process before Prefect loads settings. Common reasons it still uses the default: - The env var isn’t set in the worker/job environment (e.g., set in your shell, but your Docker/Kubernetes worker runs with a different env). - It’s set after Prefect is imported (settings are resolved at startup). - You’re setting it in one place (e.g., agent/worker) but not in the actual runtime (e.g., Kubernetes job spawned by the worker). - The path isn’t writable or doesn’t exist, and something in your setup falls back to default. What to do: - Make sure the variable is set where the run actually executes. - Docker worker: set it on the worker container env (and any job container, if different). - Kubernetes worker: add it to the worker Pod env and to the job env via your work pool/deployment. - Set it before the process starts. - Alternatively, set
PREFECT_HOME=/home/prefect/cache
and let Prefect use
/home/prefect/cache/storage
as the default. Create the directory and ensure it’s writable. Quick check inside your flow (early, before importing much else) to confirm what the run sees:
Copy code
import os
print("PREFECT_LOCAL_STORAGE_PATH =", os.getenv("PREFECT_LOCAL_STORAGE_PATH"))
print("PREFECT_HOME =", os.getenv("PREFECT_HOME"))
If you’re on Prefect 2.x, note that storage blocks or deployment-specific settings can override globals. In 3.x,
PREFECT_LOCAL_STORAGE_PATH
and/or
PREFECT_HOME
should be sufficient if correctly set in the runtime. Docs for reference: - Settings and profiles (how Prefect resolves settings): Settings &amp; Profiles If you share: - Your Prefect version - How you’re running (worker type, Docker/K8s/etc.) - Where you set the env var(s) …I can point at the exact place to set it so Prefect stops being “helpful” and writing to
~/.prefect/storage
.
b
@Marvin I'm using version 3.4.13 using kubernetes workers, environment variables are set in a configmap referenced by the pod running the flow
m
thought for 120.3 seconds
Thanks — that helps narrow it down. In Prefect 3.4.x, the default local results path is derived from
PREFECT_HOME
as
{PREFECT_HOME}/storage
. The
PREFECT_LOCAL_STORAGE_PATH
variable you’re setting is not a documented/recognized setting in 3.x, so Prefect keeps using the default
{home}/.prefect/storage
. Given you’re on Kubernetes workers: - Set
PREFECT_HOME=/home/prefect/cache
in the job pod’s environment (not just the worker pod). - Ensure
/home/prefect/cache/storage
exists and is writable by the container user. - If you’re using a ConfigMap, make sure it’s referenced by the job template used by the work pool so the job pod actually sees it. Quick ways to verify in the running flow pod:
Copy code
import os
print("PREFECT_HOME =", os.getenv("PREFECT_HOME"))
print("PREFECT_LOCAL_STORAGE_PATH =", os.getenv("PREFECT_LOCAL_STORAGE_PATH"))
If
PREFECT_HOME
is unset in the job pod, Prefect will fall back to
/home/prefect/.prefect/storage
. Example snippet for your Kubernetes work pool job template to ensure the env var is present and the path exists/mounted:
Copy code
pod:
  env:
    - name: PREFECT_HOME
      value: /home/prefect/cache
  volumeMounts:
    - name: cache
      mountPath: /home/prefect/cache
  volumes:
    - name: cache
      emptyDir: {}  # or use a PVC if you want persistence
Or, if you prefer to inject via ConfigMap:
Copy code
pod:
  envFrom:
    - configMapRef:
        name: your-configmap-with-prefect-home
Reference: Settings &amp; Profiles If you can share your work pool’s job template (or how you attach the ConfigMap to the job pods), I can point at the exact spot to fix.
b
@Marvin PREFECT_LOCAL_STORAGE_PATH is documented on https://docs.prefect.io/v3/api-ref/settings-ref#local-storage-path as a supported environment variable for setting
local_storage_path
m
thought for 50.9 seconds
You’re right — thanks for the link.
PREFECT_LOCAL_STORAGE_PATH
is a valid setting in 3.x and maps to
local_storage_path
. If Prefect is still writing to
/home/prefect/.prefect/storage
, it usually means the job pod isn’t actually seeing your env var at runtime, or something else is forcing the default. Quickest way to confirm inside the flow pod:
Copy code
import os
from prefect.settings import get_current_settings

print("env PREFECT_LOCAL_STORAGE_PATH =", os.getenv("PREFECT_LOCAL_STORAGE_PATH"))
s = get_current_settings()
print("effective local_storage_path =", s.local_storage_path)
print("PREFECT_HOME (effective) =", s.home)
Checklist for Kubernetes workers: - Put the env var on the job pod, not just the worker. The worker’s env does not automatically propagate to submitted jobs. Add it to the work pool’s job template or the deployment’s pod spec. - Ensure the target path exists and is writable. Mount an
emptyDir
or PVC at
/home/prefect/cache/storage
(or whatever you’re setting). - If you want belt-and-suspenders, also set
PREFECT_HOME=/home/prefect/cache
so the default
{PREFECT_HOME}/storage
aligns with your desired path. Example job template bits:
Copy code
pod:
  env:
    - name: PREFECT_LOCAL_STORAGE_PATH
      value: /home/prefect/cache/storage
    # optional but helpful:
    - name: PREFECT_HOME
      value: /home/prefect/cache
  volumeMounts:
    - name: cache
      mountPath: /home/prefect/cache
  volumes:
    - name: cache
      emptyDir: {}
If the snippet above shows
effective local_storage_path
is your custom path but you still see writes to
~/.prefect/storage
, please share the traceback or which component is writing there (results, source checkout, etc.). That would point to a specific code path that’s ignoring the setting — in which case we’ll file it. Docs for the setting you cited: https://docs.prefect.io/v3/api-ref/settings-ref#local-storage-path
b
@Marvin running
Copy code
logger = get_run_logger()
    <http://logger.info|logger.info>(f"PREFECT_LOCAL_STORAGE_PATH: {PREFECT_LOCAL_STORAGE_PATH}")
    <http://logger.info|logger.info>(f"current_settings: {pprint(get_current_settings())}")
Inside a flow results in this:
Copy code
PREFECT_LOCAL_STORAGE_PATH: /home/prefect/cache/storage
current_settings: None
m
thought for 64.1 seconds
Ah — your
current_settings: None
is just
pprint
being “helpful.”
pprint.pprint()
prints and returns None. Use
pprint.pformat()
or inspect specific fields. Try this inside the flow:
Copy code
from prefect.settings import get_current_settings
from pprint import pformat
import os, prefect

logger = get_run_logger()
s = get_current_settings()

<http://logger.info|logger.info>(f"prefect: {prefect.__version__}")
<http://logger.info|logger.info>(f"env PREFECT_LOCAL_STORAGE_PATH = {os.getenv('PREFECT_LOCAL_STORAGE_PATH')}")
<http://logger.info|logger.info>(f"effective local_storage_path = {s.local_storage_path}")
<http://logger.info|logger.info>(f"effective PREFECT_HOME = {s.home}")
<http://logger.info|logger.info>(f"PREFECT_PROFILE = {os.getenv('PREFECT_PROFILE')}")
<http://logger.info|logger.info>(f"all settings = {pformat(s.model_dump())}")
If
effective local_storage_path
shows
/home/prefect/cache/storage
but you still see errors about
/home/prefect/.prefect/storage
, that path is likely coming from something that uses
PREFECT_HOME
directly (not
local_storage_path
) — e.g., other internal caches. In that case, set both so everything aligns: -
PREFECT_LOCAL_STORAGE_PATH=/home/prefect/cache/storage
-
PREFECT_HOME=/home/prefect/cache
Kubernetes specifics: - Put these env vars on the job pod spec (work pool job template or deployment), not just the worker pod. - Mount the path and ensure it’s writable by the container user:
Copy code
pod:
  env:
    - name: PREFECT_HOME
      value: /home/prefect/cache
    - name: PREFECT_LOCAL_STORAGE_PATH
      value: /home/prefect/cache/storage
  volumeMounts:
    - name: cache
      mountPath: /home/prefect/cache
  volumes:
    - name: cache
      emptyDir: {}  # or a PVC if you want persistence
If
effective local_storage_path
is correct but you still get a traceback referencing
~/.prefect/storage
, paste that traceback. We can identify which component is ignoring the setting and squash it accordingly. Docs you cited for the setting: local_storage_path