PaddlePaddle/PaddleOCR · error · OSError
Failed to mkdir {}
Error message
Failed to mkdir {} What it means
OSError from ppocr/utils/save_load.py mkdir_if_not_exists: os.makedirs(path) failed with an OSError that is NOT the benign EEXIST-race (another process just created the same directory). Typical causes are permission denied on a parent directory, a path component that is actually a file, a read-only filesystem, or an invalid path string.
Source
Thrown at ppocr/utils/save_load.py:63
FLAGS_json_format_model = get_FLAGS_json_format_model()
def _mkdir_if_not_exist(path, logger):
"""
mkdir if not exists, ignore the exception when multiprocess mkdir together
"""
if not os.path.exists(path):
try:
os.makedirs(path)
except OSError as e:
if e.errno == errno.EEXIST and os.path.isdir(path):
logger.warning(
"be happy if some process has already created {}".format(path)
)
else:
raise OSError("Failed to mkdir {}".format(path))
def load_model(config, model, optimizer=None, model_type="det", ema=None):
"""
load model from checkpoint or pretrained_model
"""
logger = get_logger()
global_config = config["Global"]
checkpoints = global_config.get("checkpoints")
pretrained_model = global_config.get("pretrained_model")
best_model_dict = {}
is_float16 = False
is_nlp_model = model_type == "kie" and config["Architecture"]["algorithm"] not in [
"SDMGR"
]
if is_nlp_model is True:
# NOTE: for kie model dsitillation, resume training is not supported nowView on GitHub (pinned to 2661c7c0ef)
Solutions
- Check permissions along the whole path and fix ownership (chown/chmod) or choose a writable output_dir in the config.
- Remove or rename any regular file that collides with a directory component of the path.
- On containerized runs, ensure the volume is mounted rw and the process user can write it.
- Re-run after fixing — the message names the exact failing path.
Example fix
# before Global: save_model_dir: /opt/models/output # not writable # after Global: save_model_dir: ./output
Defensive patterns
Strategy: validation
Validate before calling
import os
def ensure_writable_dir(path) -> None:
parent = os.path.dirname(os.path.abspath(path)) or '.'
assert os.path.isdir(parent), f'{parent} is not a directory'
assert os.access(parent, os.W_OK), f'no write permission under {parent}'
os.makedirs(path, exist_ok=True)
ensure_writable_dir(cfg['Global']['save_model_dir']) Try / catch
try:
os.makedirs(path, exist_ok=True)
except OSError as e:
if e.errno == errno.EACCES:
# pick a writable fallback root instead of failing the whole run
path = os.path.join(tempfile.gettempdir(), os.path.basename(path))
os.makedirs(path, exist_ok=True)
else:
raise Prevention
- Use writable, preferably relative output roots (./output) in configs.
- In containers, verify the process user can write mounted volumes before long runs.
- Never name a regular file the same as an intended output directory.
When it happens
Trigger: Training/inference saving checkpoints, inference results, or visualization outputs to a directory that cannot be created: no write permission under the output root, a file occupying a path component (e.g. ./output exists as a file), or NFS/container read-only mounts.
Common situations: Running in Docker as non-root against a host-mounted volume; output_dir in config pointing into a protected path like /opt or /; leftover files named like the intended directory; multiprocess training where the race branch is handled but real permission errors are not.
Related errors
- File not found: ${path}
- destination is required.
- {parent}
- Destination parent must be a directory: {parent}
- {destination}
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/c70cb8c7b276fb01.
Report an issue: GitHub.