Invalid Cross-Device Link
Production Risk
Common in file upload pipelines — temp files are on tmpfs, final storage is on a different filesystem.
EXDEV (errno 18) is returned when rename() or link() is called with source and destination on different filesystems. Hard links and atomic renames cannot cross filesystem boundaries.
- 1Calling rename() with source and destination on different filesystems or mount points
- 2Calling link() (hard link) across filesystem boundaries
- 3Moving a file from /tmp (tmpfs) to /home (ext4) with a library that uses rename() internally
Renaming a file from /tmp to /home on a different filesystem.
import os
os.rename('/tmp/upload.tmp', '/home/user/upload.jpg')
# OSError: [Errno 18] Invalid cross-device linkexpected output
OSError: [Errno 18] Invalid cross-device link: '/tmp/upload.tmp' -> '/home/user/upload.jpg'
Fix
Copy then delete instead of rename across devices
WHEN When the source and destination are on different filesystems
import shutil, os
shutil.copy2('/tmp/upload.tmp', '/home/user/upload.jpg')
os.unlink('/tmp/upload.tmp')
# Or use shutil.move() which handles EXDEV automaticallyWhy this works
shutil.move() detects EXDEV and falls back to copy+delete automatically. Use it instead of os.rename() when the destination may be on a different filesystem.
✕ Use os.rename() for moves that may cross filesystem boundaries
rename() is only atomic within the same filesystem. For cross-device moves, always use copy+delete or shutil.move().
Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev