pytest-dev/pytest · error · OSError

The temporary directory {rootdir} is a symbolic link. Fix th

Error message

The temporary directory {rootdir} is a symbolic link. Fix this and try again.

What it means

Raised by TempPathFactory.getbasetemp as an OSError when the auto-created basetemp root directory (typically /tmp/pytest-of-<user>) is itself a symbolic link. pytest deliberately refuses to follow a symlink here to avoid a TOCTOU symlink-swapping attack where another user redirects the shared temp root to an attacker-controlled location. The stat is taken without following symlinks where the platform allows it.

Source

Thrown at src/_pytest/tmpdir.py:189

            # temproot is usually shared).
            # Also, to keep things private, fixup any world-readable temp
            # rootdir's permissions. Historically 0o755 was used, so we can't
            # just error out on this, at least for a while.
            # Don't follow symlinks, otherwise we're open to symlink-swapping
            # TOCTOU vulnerability.
            # This check makes us vulnerable to a DoS - a user can `mkdir
            # /tmp/pytest-of-otheruser` and then `otheruser` will fail this
            # check. For now we don't consider it a real problem. otheruser can
            # change their TMPDIR or --basetemp, and maybe give the prankster a
            # good scolding.
            uid = get_user_id()
            if uid is not None:
                stat_follow_symlinks = (
                    False if os.stat in os.supports_follow_symlinks else True
                )
                rootdir_stat = rootdir.stat(follow_symlinks=stat_follow_symlinks)
                if stat.S_ISLNK(rootdir_stat.st_mode):
                    raise OSError(
                        f"The temporary directory {rootdir} is a symbolic link. "
                        "Fix this and try again."
                    )
                if rootdir_stat.st_uid != uid:
                    raise OSError(
                        f"The temporary directory {rootdir} is not owned by the current user. "
                        "Fix this and try again."
                    )
                if (rootdir_stat.st_mode & 0o077) != 0:
                    chmod_follow_symlinks = (
                        False if os.chmod in os.supports_follow_symlinks else True
                    )
                    rootdir.chmod(
                        rootdir_stat.st_mode & ~0o077,
                        follow_symlinks=chmod_follow_symlinks,
                    )
            keep = self._retention_count
            if self._retention_policy == "none":

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Remove the symlink: `rm /tmp/pytest-of-<user>` and let pytest recreate it as a real directory.
  2. Set a safe basetemp explicitly via `pytest --basetemp=/real/dir` or TMPDIR env var pointing at a non-symlink directory.
  3. If the OS layout forces a symlink at /tmp, point TMPDIR to a real directory on a non-linkified filesystem.
  4. Audit setup scripts and provisioning that may `ln -s` into /tmp.

Example fix

// before
# /tmp/pytest-of-alice -> /mnt/big/pytest-alice (symlink)
$ pytest tests/

// after
$ rm /tmp/pytest-of-alice
$ TMPDIR=/mnt/big/realtmp pytest tests/
# or
$ pytest --basetemp=/mnt/big/realtmp/pytest-alice tests/
Defensive patterns

Strategy: validation

Validate before calling

import os, pathlib

def ensure_basetemp_not_symlink(p: pathlib.Path):
    if p.is_symlink():
        raise OSError(f"{p} is a symlink; refusing to use as basetemp")
    return p

Type guard

import os

def is_real_dir(p) -> bool:
    return os.path.isdir(p) and not os.path.islink(p)

Prevention

When it happens

Trigger: Someone (a human, a setup script, or another tool) created /tmp/pytest-of-<user> as a symlink to elsewhere, then pytest tries to initialize its basetemp under it. Triggered on the first test/fixture that needs tmp_path or any call to tmp_path_factory.getbasetemp().

Common situations: Shared CI runners where /tmp is symlinked (e.g. to a larger disk); a previous `ln -s` for debugging; Docker/k8s volume mounts that manifest as symlinks; misconfigured TMPDIR pointing at a symlinked dir.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/d01c0c2d9c824590.json. Report an issue: GitHub.