django/django · warning · SuspiciousFileOperation
File name '%s' includes path elements
Error message
File name '%s' includes path elements
What it means
Raised as a django.core.exceptions.SuspiciousFileOperation by validate_file_name() (the default code path, allow_relative_path=False) when the given name is not equal to its own basename — i.e. it contains '/', '\', or other path separators. Django requires file names to be bare names so the storage backend can place them safely; any embedded path is rejected.
Source
Thrown at django/core/files/utils.py:21
from django.core.exceptions import SuspiciousFileOperation
def validate_file_name(name, allow_relative_path=False):
# Remove potentially dangerous names
if os.path.basename(name) in {"", ".", ".."}:
raise SuspiciousFileOperation("Could not derive file name from '%s'" % name)
if allow_relative_path:
# Ensure that name can be treated as a pure posix path, i.e. Unix
# style (with forward slashes).
path = pathlib.PurePosixPath(str(name).replace("\\", "/"))
if path.is_absolute() or ".." in path.parts:
raise SuspiciousFileOperation(
"Detected path traversal attempt in '%s'" % name
)
elif name != os.path.basename(name):
raise SuspiciousFileOperation("File name '%s' includes path elements" % name)
return name
class FileProxyMixin:
"""
A mixin class used to forward file methods to an underlying file
object. The internal file object has to be called "file"::
class FileProxy(FileProxyMixin):
def __init__(self, file):
self.file = file
"""
encoding = property(lambda self: self.file.encoding)
fileno = property(lambda self: self.file.fileno)
flush = property(lambda self: self.file.flush)
isatty = property(lambda self: self.file.isatty)View on GitHub (pinned to ae25a40be0)
Solutions
- Flatten the name to its basename: name = os.path.basename(name) before calling save().
- If you need subdirectories, use a storage backend/path that supports it and pass allow_relative_path=True only after sanitizing (see error 400).
- Construct flat, unique names yourself, e.g. name = f'{uuid4().hex}.pdf'.
Example fix
// before
storage.save(os.path.join('uploads', upload.name), content)
// after
storage.save(os.path.basename(upload.name), content) Defensive patterns
Strategy: validation
Validate before calling
import os
def flat_name(name):
base = os.path.basename(str(name).replace('\\', '/'))
if base in ('', '.', '..'):
raise ValueError(f'cannot derive a flat name from {name!r}')
return base Type guard
import os
def is_flat_filename(name: str) -> bool:
return name == os.path.basename(str(name).replace('\\', '/'))
Try / catch
from django.core.exceptions import SuspiciousFileOperation
try:
storage.save(name, content)
except SuspiciousFileOperation:
storage.save(os.path.basename(name), content) Prevention
- Never embed directories in names passed to storage.save / FileField.
- Use os.path.basename() defensively at the boundary where untrusted names enter.
- Generate flat unique names yourself instead of preserving client subpaths.
When it happens
Trigger: Calling storage.save('subdir/file.txt', content) or FieldFile.save with a name containing a slash; passing a full Windows path like 'C:\\tmp\\f.txt'; assigning a model FileField a value containing directory separators.
Common situations: Saving uploads preserving the original browser sub-path; generating names with os.path.join('user_1', 'doc.pdf') instead of a flat name; copying paths from an external source into storage.save.
Related errors
- password_too_short
- Detected path traversal attempt in '%s'
- Invalid address {address!r}: {'; '.join(defects)}
- null_characters_not_allowed
- The SECRET_KEY setting must not be empty.
AI-assisted analysis of django/django@ae25a40be0 (2026-08-06).
Data as JSON: /api/errors/fc7bc26fdb443c77.
Report an issue: GitHub.