Forbidden characters
Windows rejects these outright. Linux allows almost anything.
<>:"/\|?*Trap: report:2024.txt is legal on Linux, impossible on Windows โ sync skips it.
Try: question?name.txt ยท double"quote.txt
What breaks when files move between ๐ช Windows, ๐ macOS and ๐ง Linux โ characters, reserved names, path separators, zero-byte files and more. Scan the matrix, then dig into any row.
| Rule | ๐ชWindows | ๐macOS | ๐งLinux |
|---|---|---|---|
Special chars : * ? " < > | |
โforbidden | !avoid : |
โallowed |
Backslash \ in a name |
โpath separator | โordinary char | โordinary char |
Reserved names CON NUL |
โforbidden | โallowed | โallowed |
| Case-sensitive names | โmerges | โmerges (default) | โdistinct |
| Unicode NFC = NFD | !bytes as-is | !stores NFD | !bytes as-is |
Trailing . or space |
โstripped | โkept | โkept |
| Path length | !260 default | โ1024 | โ4096 |
| Zero-byte file | โ"0 KB" | โ"Zero bytes" | โ0 |
| Text line endings | !CRLF | !LF | !LF |
Windows rejects these outright. Linux allows almost anything.
<>:"/\|?*Trap: report:2024.txt is legal on Linux, impossible on Windows โ sync skips it.
Try: question?name.txt ยท double"quote.txt
/ vs \The single biggest cross-platform path bug.
Trap: on Linux, folder\file is one filename containing a backslash. Move it to Windows and it becomes a folder โ file path โ or fails. Web URLs are always /.
Try: backslash\name.txt
Windows keeps legacy device names โ even with an extension.
CONPRNAUXNULCOM1โ9LPT1โ9Trap: CON.txt and nul.log can't be created or extracted on Windows.
Are File.txt and file.txt the same file?
Trap: a repo with README.md + Readme.md loses one file when cloned on Windows/Mac.
cafรฉ can be 4 code points (NFC) or 5 (NFD). Same look, different bytes.
Trap: a Mac-saved cafรฉ.txt won't match the same name typed on Windows โ "file not found" for a name you can see.
Try: nfc-cafรฉ.txt vs nfd-cafรฉ.txt
Windows silently strips a trailing . or space.
Trap: report. becomes report โ two files collide into one.
Try: trailing-dot.txt.
Per-name and full-path caps.
Names: 255 units (Win/Mac) or 255 bytes (Linux โ so ~63 emoji). *Windows lifts 260 only with long-path mode.
Try: a 204-char name
A file with no content is valid everywhere โ but shown and handled differently.
Trap: upload validators that check MIME but not size > 0 accept empty files; some sync clients skip them; Git needs an explicit add. Used deliberately as markers (.gitkeep).
Try: 0b.bin (exactly 0 bytes)
Same text, different bytes per platform.
\r\n CRLF\n LF\n LFTrap: breaks diffs, checksums and line-by-line parsers. Classic Mac used bare \r (CR).
OneDrive, Dropbox and Drive apply the strictest (Windows-style) rules on every platform, plus extra reserved names and path caps.
" * : < > ? / \ |, .lock, CONโฆLPT9, ~$โฆ, leading/trailing spaces, ~400-char paths/ \ < > : " | ? *, .dropbox, desktop.ini; case-insensitive; no trailing spaces/dotsSafe-everywhere rule: use only AโZ aโz 0โ9 . _ -, no leading/trailing dots or spaces, avoid Windows reserved names, keep paths under ~255 chars, normalize Unicode to NFC.
Every rule above has a matching test file in the catalog โ upload one and confirm your app fails gracefully, not silently.