dotnet/machinelearning · error · EndOfStreamException
A quoted field opened on line
Error message
A quoted field opened on line {lineNum} was never closed, and we've read to the last line in the file without finding the closing quote What it means
While reading a CSV/text file with quoted fields, TextLoaderCursor.LineReader keeps reading subsequent lines to find the closing quote of a multi-line quoted field. If the stream ends (ReadLine returns null) before the closing quote is found, it throws EndOfStreamException, meaning the file's quoting is malformed or truncated.
Solutions
- Fix the source file so every quoted field is closed, or remove/escape the stray quote character reported on the given line
- Re-export or re-download the file completely and verify it is not truncated
- Check the TextLoader quoting settings (quoteChar, hasHeader, separator) match the actual file format
Example fix
// before: malformed data "name,score alice,1 // after: properly closed quote "name,score" alice,1
Defensive patterns
Strategy: validation
Validate before calling
static bool HasBalancedQuotes(string line)
{
int count = 0;
foreach (char c in line) if (c == '"') count++;
return count % 2 == 0;
} Try / catch
try { data = loader.Load(path); }
catch (EndOfStreamException ex) when (ex.Message.Contains("quoted field"))
{ log.Error("Malformed/truncated CSV: unterminated quoted field", ex); throw new InvalidDataException("Source file has unbalanced quotes", ex); } Prevention
- Validate CSV files for balanced quotes before loading (count quote chars per record)
- Verify downloaded/exported files are complete (size or checksum check)
- Match the loader's quoteChar/separator settings to the actual file format
- Escape or remove stray quote characters in source data
When it happens
Trigger: Calling LoadFromTextFile / TextLoader on a file where a quote character opens a field on some line (reported as lineNum) and the file ends without the matching closing quote.
Common situations: Truncated downloads or partial file writes; CSV data exported with unbalanced quotes; a stray quote character in data (e.g. an inch mark) that the reader interprets as opening a quoted field; wrong separator/quote-char settings misparsing the file.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Decimal separator cannot match the column separator
- Empty file
- Expected a seekable stream
- Expected either or to be provided
- kind
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/0e7b42f8d5b469a0.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.ML.Data/DataLoadSave/Text/TextLoaderCursor.cs:533
if (line[0] == '/' && line[1] == '/')
return line;
if (ignoreHashLine && line[0] == '#')
return line;
// Get more lines until the last field of the line doesn't contain its newline
// inside a quoted field
bool lastFieldIncludesNewLine = LastFieldIncludesNewLine(line, false);
if (!lastFieldIncludesNewLine)
return line;
_sb.Clear();
_sb.Append(line);
while (lastFieldIncludesNewLine)
{
line = _rdr.ReadLine();
if (line == null)
throw new EndOfStreamException($"A quoted field opened on line {lineNum} was never closed, and we've read to the last line in the file without finding the closing quote");
_sb.Append("\n");
_sb.Append(line);
lastFieldIncludesNewLine = LastFieldIncludesNewLine(line, true);
}
return _sb.ToString();
}
// The startsInsideQuoted parameter indicates if the last field of the previous line
// ended in a quoted field which included the newline character,
// if it is true, then the beginning of this line is considered to be part
// of the last field of the previous line.
public bool LastFieldIncludesNewLine(string line, bool startsInsideQuoted = false)
{
if (line.Length == 0)
return startsInsideQuoted;
View on GitHub (pinned to 7b76e69cf9)