NFD NFC filename problems on web uploads: 5 symptoms, fixed
If a file you uploaded from a Mac shows up on a website with the name looking slightly wrong, a download link that returns "file not found", or a name that search simply cannot find, you are almost certainly looking at an NFD NFC filename problem. macOS stores accented and non-Latin characters in a decomposed Unicode form (NFD), while most web servers, content management systems and browsers expect the composed form (NFC). The fix is to rename the file into NFC before you upload it, or to have the server normalize on receipt. Below are the five symptoms this causes on websites, what each one means, and the quickest way to fix it.
How NFD NFC filename trouble starts
A character like é can be written two ways in Unicode. The composed way is one code point, U+00E9. The decomposed way is two: a plain e followed by a combining acute accent. Both look identical on screen. Korean is the same story at a larger scale: 한글 can be stored as two composed syllables or as a chain of separate jamo. Japanese kana with dakuten, such as が, can be stored as one character or as か plus a separate voicing mark.
macOS has historically produced the decomposed (NFD) version when you save a file with such a name. Almost everything else, including Windows, Linux servers, PHP, Node, Python web frameworks and the browsers that render the result, assumes NFC. When an NFD name travels into a system that assumes NFC, the system does not "fix" it; it treats it as a different string. That single mismatch explains every symptom that follows.
This affects anyone whose filenames contain non-ASCII characters: a report named Résumé_José_Martínez.pdf, a photo called Zoë_birthday.jpg, a spreadsheet from a Korean colleague named 예산안_2026.xlsx, or a Japanese PDF called がいよう.pdf. If your names are pure ASCII (report_2026.pdf), none of this applies to you.
The five symptoms, and the fix for each
1. Accents or letters appear detached after upload
What you see: The file list in your CMS, learning platform or client portal shows Jose´.pdf with the accent floating, or a Korean name rendered as ㅎㅏㄴㄱㅡㄹ.docx with each letter separated. On other systems the name looks fine.
Why: The website's font or rendering layer does not know how to combine the base letter with the separate combining mark, so it draws them side by side.
Fix: Rename the file to NFC before uploading and upload it again. If the platform does not allow deleting the broken entry, ask the site administrator to remove it, because uploading a fixed version will likely create a second file rather than replace the first (see symptom 4).
2. The download link returns 404 or "file not found"
What you see: The file uploaded without error. It shows in the media library. Clicking the link gives a 404, or the page says the file does not exist.
Why: The server stored the file under its NFD name, but the link it generated, or the database record it saved, was normalized to NFC somewhere along the way. The URL points to a name that is one byte sequence off from the real file on disk. Both look identical in the address bar.
Fix: For a one-off, re-upload with an NFC name. If this happens on your own site, the real fix is server-side: normalize every incoming filename to NFC before saving. In Python that is unicodedata.normalize("NFC", name); in JavaScript it is name.normalize("NFC"); in PHP, Normalizer::normalize($name, Normalizer::FORM_C). Do it once at the upload boundary and the problem disappears for all users.
3. Search cannot find the file, even though it is right there
What you see: You type José into the site's search box, or press Ctrl+F on the file list, and nothing matches. You can see the file in the list.
Why: Search compares byte sequences. You typed NFC; the stored name is NFD. They are not equal, so there is no match. The same thing happens in some email clients when searching attachment names.
Fix: Rename to NFC and re-upload. As a workaround, search for the part of the name that has no accents (Mart instead of Martínez), which will match either form.
4. "A file with this name already exists", or two identical-looking files
What you see: The platform refuses the upload, or you end up with two files that appear to have exactly the same name.
Why: One copy is NFD, the other NFC. To the system they are two different names, so it either sees a conflict in a name-mapping table or happily stores both.
Fix: Delete the NFD copy, keep the NFC one. If you cannot tell which is which by looking, download both and check (see "How to tell which form a filename is in" below).
5. Scripts, imports or forms reject the filename
What you see: A bulk importer, a form that validates filenames, or a build script fails with a message about invalid characters, even though the name contains only ordinary letters.
Why: Validation rules written as regular expressions often allow precomposed accented letters but not combining marks. A decomposed é contains U+0301, which many "letters only" patterns do not permit.
Fix: Normalize to NFC before the file reaches the validator. If you own the validator, normalize the input first, then validate.
How to tell which form a filename is in
You cannot tell by looking, which is the whole problem. Three reliable checks:
- On a Mac, in Terminal:
ls | xxd | head. A composed é appears asc3 a9. A decomposed one appears as65 cc 81(thee, then the combining accent). - On Windows, in PowerShell:
[int[]][char[]]"José"prints the code points.233is composed;101, 769is decomposed. - In any browser console:
"José".normalize("NFD") === "José"returnstrueif the string you pasted is already NFD.
Retyping the name by hand in Finder sometimes produces NFC and sometimes does not, depending on the filesystem and how the name was entered, so retyping is not a dependable fix on its own.
Fixing filenames in bulk before you upload
For one or two files, retyping the name on a Windows machine, or renaming on the server after upload, is fine. For a folder of 80 photos with accented names, or a semester's worth of Korean course material, that stops being practical.
Options that do not need any extra tool:
- Use ASCII-only names.
Jose_Martinez_CV.pdfcan never hit this problem. It is the most robust choice for anything that will be linked publicly. - Normalize with a one-line script. On macOS, Python is available:
for f in *; do mv "$f" "$(python3 -c 'import sys,unicodedata;print(unicodedata.normalize("NFC",sys.argv[1]))' "$f")"; done. This works, but it will rename things you did not intend if you run it in the wrong folder. - Fix it on the server. If you control the site, normalizing on upload protects every future user, not just you.
If you would rather not run scripts, FilenameFixer is a free web app that does exactly this conversion. You drag the files into the browser, it renames them from NFD to NFC in a batch, and the processing happens locally in your browser rather than on a server. It also accepts pasted text, which is handy for checking a single name quickly, and it can restore filenames inside ZIP archives up to 200 MB. For the upload scenario specifically, the companion Chrome extension normalizes filenames automatically at the moment you upload them to a website, so symptoms 1 through 5 do not happen in the first place. The site is available in English, Korean, Japanese, French, German, Spanish and Vietnamese.
One honest limit: none of these approaches can repair a file that is already sitting on the server under a broken name. For those, delete and re-upload, or ask whoever runs the site to rename it on disk.
Quick reference
| Symptom | Where it bites | Fix |
|---|---|---|
| Detached accents or separated letters | File list, media library | Rename to NFC, re-upload |
| 404 on download link | Public URL, CMS | Re-upload; normalize server-side |
| Search finds nothing | Site search, Ctrl+F, email | Rename to NFC; search the unaccented part |
| Duplicate or "already exists" | Uploads, shared folders | Delete the NFD copy |
Once you know that two identical-looking names can be different strings, every one of these symptoms becomes predictable. Normalize to NFC before the file leaves your Mac, or at the server's front door, and the website will treat the name the way you expected it to all along.