A tool says my CSV is not UTF-8, but it looks fine

Encoding detectors read a sample from the start of the file. If nothing distinguishing lives there, the answer is a guess — and on one 3.3MB file the deciding byte was at offset 128,268.

What you are seeing

A validator or import tool flags an encoding problem. You open the file and every character looks correct.

There is no error message for this one. That is the problem, not an omission on this page — the import reports success and the damage is only visible if you go looking for it.

Why it happens

Character-encoding detection is statistical, and it works on a sample. Two things make that sample lie, and we hit both in our own code before we fixed it.

First, a file containing no byte above 0x7F is pure ASCII, and every 8-bit encoding decodes it identically. A detector asked to rank encodings for such a file is choosing between answers that are all correct, and it may return a confident non-UTF-8 verdict that means nothing at all.

Second, the sample may simply miss the evidence. One 3.3MB supplier CSV in our corpus has its first byte above 0x7F at offset 128,268 — twice the 64KB a detector had read. It was ranking encodings from a window in which nothing distinguished them.

None of which means encoding problems are imaginary. Another file in the same corpus has 48 non-ASCII bytes that decode to 48 replacement characters as UTF-8 and cleanly as windows-1252. That one genuinely is not UTF-8, and it keeps its blocker.

How to fix it

  1. Check whether the file has any byte above 0x7F at all. If it does not, the encoding question is moot and any tool insisting otherwise is wrong.
  2. If it does, find the FIRST such byte and look at the text around it. That is where the evidence is, and it may be nowhere near the beginning of the file.
  3. Decode the whole file as UTF-8 and count replacement characters. A real encoding problem produces them; a detector guessing about an ASCII file does not.

Where this came from

We broke a real Shopify store on purpose to answer these questions, and kept what it said. Nothing on this page is quoted from documentation.

  • A 3.3MB supplier CSV was called not-UTF-8 by an encoding detector reading its first 64KB, when its first byte above 0x7F sits at offset 128,268 — the detector was ranking encodings from a window in which nothing distinguished them. Three further files carry no byte above 0x7F at all, so every 8-bit encoding decodes them identically.

What we did not measure. This describes how detection fails and how to settle it by hand. It does not tell you which encoding a genuinely non-UTF-8 file is in — that still takes looking at the bytes.

Observed 2026-09-04. The store this was measured on has since been deleted, so these answers are an archive rather than something we re-run — we would rather tell you the date than imply it is checked continuously.

Check your file before you upload it

The Pre-Flight Report reads your supplier file and names every blocker, with the row it is on, before you go near an importer. It is free, it needs no account, and it does not send your file to a model.

Check a file free