Repository: iterative/dvc

Issue:
`DVC_SITE_CACHE_DIR` environment variable does not override `.dvc/config` settings
# Bug Report


## Description

The documentation on [environment variables](https://dvc.org/doc/user-guide/env#environment-variables) says:
>  DVC_SITE_CACHE_DIR: Directory for the [site cache dir](https://dvc.org/doc/user-guide/project-structure/internal-files#site-cache-dir). Overrides [dvc config core.site_cache_dir](https://dvc.org/doc/command-reference/config).

However, this is not working as expected and if `core.site_cache_dir` is set in `.dvc/config`, the environment variable is ignored.

### Reproduce

Setup repo with `site_cache_dir` configuration:
```console
mkdir test_repo
cd test_repo
dvc init --no-scm
dvc config core.site_cache_dir /tmp/not_this_dir/
```

Check information:
```console
$ env DVC_SITE_CACHE_DIR=/tmp/use_this_dir/ dvc doctor
DVC version: 3.60.0 (conda)
---------------------------
Platform: Python 3.10.18 on macOS-15.5-x86_64-i386-64bit
Subprojects:
        dvc_data = 3.16.10
        dvc_objects = 5.1.1
        dvc_render = 1.0.2
        dvc_task = 0.40.2
        scmrepo = 3.3.11
Supports:
        gdrive (pydrive2 = 1.21.3),
        http (aiohttp = 3.9.5, aiohttp-retry = 2.9.1),
        https (aiohttp = 3.9.5, aiohttp-retry = 2.9.1),
        s3 (s3fs = 2025.5.1, boto3 = 1.37.3),
        ssh (sshfs = 2025.2.0)
Config:
        Global: /Users/rgoya/Library/Application Support/dvc
        System: /Library/Application Support/dvc
Cache types: <https://error.dvc.org/no-dvc-cache>
Caches: local
Remotes: None
Workspace directory: apfs on /dev/disk1s5s1
Repo: dvc (no_scm)
Repo.site_cache_dir: /tmp/not_this_dir/repo/c58163f0b6f80c77503e8859c67a9713
```

### Expected

The documentation states that `DVC_SITE_CACHE_DIR=/tmp/use_this_dir/` should override the config, so the last line should have read:
```console
Repo.site_cache_dir: /tmp/use_this_dir/repo/c58163f0b6f80c77503e8859c67a9713
```


Discussion:
FYI, I have released [`dvc==3.60.1`](https://github.com/iterative/dvc/releases/tag/3.60.1) with your fixes.

Thank you for reporting and fixing!
> FYI, I have released [`dvc==3.60.1`](https://github.com/iterative/dvc/releases/tag/3.60.1) with your fixes.
> 
> Thank you for reporting and fixing!

That's amazing, thank you! Glad to help.



Patch:
diff --git a/dvc/dirs.py b/dvc/dirs.py
index 881a30840a..eef78f856c 100644
--- a/dvc/dirs.py
+++ b/dvc/dirs.py
@@ -1,4 +1,5 @@
 import os
+from typing import Optional
 
 import platformdirs
 
@@ -20,13 +21,16 @@ def global_config_dir():
     )
 
 
-def site_cache_dir():
+def site_cache_dir(config_site_cache_dir: Optional[str] = None):
     from platformdirs import PlatformDirs
     from platformdirs.unix import Unix
 
     if dvc_site_cache_dir := os.getenv(env.DVC_SITE_CACHE_DIR):
         return dvc_site_cache_dir
 
+    if config_site_cache_dir is not None:
+        return config_site_cache_dir
+
     if issubclass(Unix, PlatformDirs):
         # Return the cache directory shared by users, e.g. `/var/tmp/$appname`
         # NOTE: platformdirs>=5 changed `site_cache_dir` to return /var/cache/$appname.
diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py
index 2b89626972..9f296f85ed 100644
--- a/dvc/repo/__init__.py
+++ b/dvc/repo/__init__.py
@@ -609,7 +609,7 @@ def site_cache_dir(self) -> str:
         from dvc.fs import GitFileSystem
         from dvc.version import version_tuple
 
-        cache_dir = self.config["core"].get("site_cache_dir") or site_cache_dir()
+        cache_dir = site_cache_dir(self.config["core"].get("site_cache_dir"))
 
         subdir = None
         if isinstance(self.fs, GitFileSystem):


Test patch:
diff --git a/tests/unit/test_dirs.py b/tests/unit/test_dirs.py
index 259a330af6..7ef79e364c 100644
--- a/tests/unit/test_dirs.py
+++ b/tests/unit/test_dirs.py
@@ -21,3 +21,13 @@ def test_site_cache_dir_on_unix(monkeypatch):
 def test_site_cache_dir_env_var(monkeypatch):
     monkeypatch.setenv(DVC_SITE_CACHE_DIR, "foo_bar")
     assert site_cache_dir() == "foo_bar"
+
+
+def test_site_cache_dir_with_config_parameter(monkeypatch):
+    monkeypatch.delenv(DVC_SITE_CACHE_DIR)
+    assert site_cache_dir(config_site_cache_dir="foo_bar") == "foo_bar"
+
+
+def test_site_cache_dir_env_var_precedence(monkeypatch):
+    monkeypatch.setenv(DVC_SITE_CACHE_DIR, "foo")
+    assert site_cache_dir(config_site_cache_dir="bar") == "foo"