goharbor/harbor · error
Path exists and the type is regular file
Error message
Path exists and the type is regular file
What it means
Thrown by prepare_dir() in make/photon/prepare/utils/misc.py when the directory it is asked to create (e.g. <data_volume>/registry, /etc/registry config dirs inside the prepare container) already exists but is a regular file (absolute_path.is_file()). Rather than overwrite or fail halfway, prepare refuses and aborts, protecting whatever content the file holds.
Source
Thrown at make/photon/prepare/utils/misc.py:68
if storage_provider_config == "":
raise Exception(
"Error: no provider configurations are provided for provider %s" % storage_provider_name)
def validate_crt_subj(dirty_subj):
subj_list = [item for item in dirty_subj.strip().split("/") \
if len(item.split("=")) == 2 and len(item.split("=")[1]) > 0]
return "/" + "/".join(subj_list)
def generate_random_string(length):
return ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(length))
def prepare_dir(root: str, *args, **kwargs) -> str:
gid, uid = kwargs.get('gid'), kwargs.get('uid')
absolute_path = Path(os.path.join(root, *args))
if absolute_path.is_file():
raise Exception('Path exists and the type is regular file')
mode = kwargs.get('mode') or 0o755
# we need make sure this dir has the right permission
if not absolute_path.exists():
absolute_path.mkdir(mode=mode, parents=True)
elif not check_permission(absolute_path, mode=mode):
absolute_path.chmod(mode)
# if uid or gid not None, then change the ownership of this dir
if not(gid is None and uid is None):
dir_uid, dir_gid = absolute_path.stat().st_uid, absolute_path.stat().st_gid
if uid is None:
uid = dir_uid
if gid is None:
gid = dir_gid
# We decide to recursively chown only if the dir is not owned by correct user
# to save time if the dir is extremely large
if not check_permission(absolute_path, uid, gid):View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Identify the offending file: the prepare log names the path being prepared when it aborts - inspect it (file <path>, cat) for valuable content
- Move it aside or delete it: mv <path> <path>.bak
- Ensure the parent data_volume is a real directory and mounts are directory mounts
- Re-run ./install.sh - prepare_dir will now mkdir and set ownership/permissions
Example fix
# on the Harbor host (before) $ ls -l /data/registry -rw-r--r-- 1 root root 0 Jan 1 00:00 /data/registry # a file! # after $ mv /data/registry /data/registry.bak $ ls -ld /data/registry mkdir happens on next ./install.sh
Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
# before calling prepare_dir(root, *args):
target = Path(root).joinpath(*args)
if target.exists() and target.is_file():
raise SystemExit('%s exists and is a regular file - move it before prepare' % target) Type guard
def is_clear_dir_path(p: str) -> bool:
"""True when p is a directory or does not exist (safe for prepare_dir)."""
path = Path(p)
return not path.exists() or path.is_dir() Prevention
- Keep data_volume clean - only Harbor-managed subdirectories should live there
- Never bind-mount single files over Harbor directory paths
- Check ls -ld <data_volume>/* after failed installs to spot file-vs-dir clashes
When it happens
Trigger: A regular file occupies the exact target path before install/prepare runs - e.g. someone created /data/registry as a file, a bind mount mounted a single file where a directory is expected, or leftover artifacts from previous experiments sit in the data_volume layout.
Common situations: Reusing a data_volume that previously held unrelated files; docker bind mounts created from single-file host paths; operators 'reserving' paths with touch; restoring partial backups where directories became files.
Related errors
- secret key's length has to be 16 chars, current length: %d
- Please specify hostname
- Can not get file info
- Error: The path for certificate key: %s is invalid
- File {} not exist
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/991054c27f0e5a78.
Report an issue: GitHub.