CSV Unterminated Quoted Field: One Missing Quote Swallows the Rest of the File
The giveaway is not an error message — it is the row count. When a quoted field is never closed, the parser keeps reading, and the newlines that were supposed to end rows become ordinary characters inside a single value.
The short answer
A field that opens with " and never closes it does not stop at the end of its line. A CSV parser treats a newline inside a quoted field as ordinary content, so it keeps reading — through the rest of that line, the next line, and every line after it — looking for the closing quote.
The consequence is a row count that collapses. Rows below the stray quote are not dropped or corrupted; they are absorbed, ending up as text inside one very large field, delimiters and line breaks intact. That collapse is the symptom worth watching for, because it is visible without reading any error message.
What actually happens
Four lines. A header and what look like 3 rows — the quote before alice is never closed:
id,name,note
1,"alice,ok
2,bob,fine
3,carl,fineMeasured through Papa Parse 5.5.4, that produces 1 row:
[
{
"id": "1",
"name": "alice,ok\n2,bob,fine\n3,carl,fine"
}
]
# Three apparent rows in. One row out.
# Everything below the opening quote became part of "name".Nothing was thrown away — every character is still there. But bob and carl are no longer rows, and the note column has no value for the one row that survived, because the parser was still inside name when the file ended. Closing the quote is the entire fix:
id,name,note
1,"alice",ok
2,bob,fine
3,carl,fineTwo different quote problems
Papa Parse separates them, and the distinction is worth keeping because only one of them collapses the row count.
MissingQuotes — Quoted field unterminated. A quote was opened and the file ended before it closed. This is the one that swallows rows.
InvalidQuotes — Trailing quote on quoted field is malformed. A quote appears inside a quoted field without being doubled. The row structure survives; the value is cut short at the stray quote, which is easy to miss precisely because the file still looks the right shape.
| Input | Looks like | Parses as | Papa reports |
|---|---|---|---|
| Quote opened and never closed, mid-fileEvery line below the open quote is absorbed into one field. | 3 rows | 1 rows | MissingQuotes |
| Quote opened on the last rowNothing follows it to absorb, so only that row loses its remaining fields. | 2 rows | 2 rows | MissingQuotes |
| A quote inside a quoted field, not doubledThe row count survives; the value is truncated at the stray quote. | 2 rows | 2 rows | InvalidQuotes |
| The same value with the inner quotes doubledCorrect. This is how a literal quote is written. | 2 rows | 2 rows | nothing |
| A quoted field that legitimately spans linesAlso correct. A closed quote may contain newlines — this is not the bug. | 3 rows | 2 rows | nothing |
| A quote in the middle of an unquoted fieldAccepted as a literal character. A quote only opens a field at its start. | 1 rows | 1 rows | nothing |
The last 3 rows are the useful controls. A quoted field spanning several lines is perfectly valid CSV, and so is a bare quote in the middle of an unquoted value — a quote only opens a field when it is the first character of one. If your file contains multi-line values and parses to fewer rows than it has lines, that is expected, not a bug.
How quoting is supposed to work
Three rules cover almost every case. A field is wrapped in double quotes when it contains the delimiter, a line break, or a double quote; and a literal double quote inside such a field is written twice:
Doe, Jane -> "Doe, Jane" # contains the delimiter
he said "hi" -> "he said ""hi""" # inner quotes are doubled
line one
line two -> "line one
line two" # newline inside a closed quote is fineNearly every unterminated quote traces back to CSV assembled by joining strings with commas. A CSV writer applies these rules for you; string concatenation does not, and the first value containing a quote or a comma breaks the file.
Finding the stray quote
- 1. Compare the row count you expected with the row count you gotThis is the fastest signal, and it needs no error message. A file that should have produced thousands of rows and produced a few hundred has a quote problem somewhere above the point where the count stops making sense.
- 2. Look at the last row that survivedOne of its fields will be enormous, containing what should have been the following rows, complete with the delimiters and newlines that were meant to separate them. That field is where the quote was opened.
- 3. Find lines with an odd number of quotesA correctly quoted line has an even count, since every field that opens a quote also closes it. Scanning for odd counts narrows a large file to a handful of candidates quickly.
- 4. Fix it at the producer, not in the fileA stray quote almost always means something wrote the CSV by concatenating strings rather than using a CSV writer. Escaping one value by hand fixes today; using a writer that doubles inner quotes fixes the class.
- 5. Re-parse and check the count againQuote problems frequently come in groups, because whatever produced one unescaped value produced others. Confirming the row count is faster than reading the file.
# Lines with an odd number of double quotes are where to look first.
awk -F'"' 'NF % 2 == 0 { print FNR": "$0 }' data.csv
# NF is one more than the number of quotes on the line, so an even NF
# means an odd quote count — a field opened or closed but not both.What other tools call it
The defect is the same everywhere; the wording is not, which is why searching for your exact message may not find much:
| Tool | Reports |
|---|---|
| Papa Parse | Quoted field unterminated (MissingQuotes) |
| PostgreSQL COPY | unterminated CSV quoted field |
| Python csv | newline inside string / unexpected end of data |
| Dataiku | ERR_DATASET_CSV_UNTERMINATED_QUOTE |
| Excel and Sheets | no message — the import simply looks wrong |
Spreadsheet applications are the awkward case: they generally report nothing at all and simply show a sheet where one cell holds several rows of text. The row count remains the reliable signal.
Checking a file
Pasting the CSV into the CSV Converter converts it to JSON, which makes the collapse immediate to see — the row count is right there, and the oversized field is visible with the absorbed rows inside it. It reports an unterminated quote separately from a row-width mismatch, so you can tell which of the two you have.
It does not repair quoting. It will not close the quote, re-split the absorbed rows, or re-escape values — the conversion shows you what a parser sees, and the correction belongs in whatever wrote the file. Conversion runs in your browser, so a file containing real data is not uploaded anywhere.
If your rows are all present
If the row count is right but the rows have different widths — some with extra values, some short — that is a different problem with a different cause and fix. Nothing is absorbed there, and no quote is involved: rows with a different field count covers what each parser does with the surplus, including the __parsed_extra key.
The short version: count the rows first. If the count collapsed, look for a quote. If the count is right and the shapes differ, look at the widths.
Versions measured
Row counts, error codes, and messages on this page were produced by:
- Papa Parse —
5.5.4 (header: true, skipEmptyLines: true) - DataToolsHQ CSV Converter —
Papa Parse 5.5.4
Other parsers word the diagnostics differently and some refuse the file outright, but the underlying behaviour is the same: an unclosed quote keeps reading.