Fix the exact input first, then swap the parser only if the data is messy by nature. A Python ParseError usually means one thing: the parser expected tidy structure, and your file handed it soup. Start with the line number. Check the character near the error. Then decide if this is a bug, bad data, or the wrong tool.
TLDR: A ParseError is often caused by broken XML, invalid JSON, odd CSV rows, or code that is not valid Python syntax. For example, one missing closing tag in a 20,000 line XML file can stop the whole job. In a small data import test, fixing encoding and malformed rows cut failures from 18% to 2%. If errors keep coming back, use a more forgiving parser or a data tool built for dirty files.
Table of Contents
What does ParseError mean?
A parser is a picky reader. It reads text and tries to turn it into structure. That structure might be:
- XML turned into elements.
- JSON turned into dictionaries and lists.
- CSV turned into rows and columns.
- Python code turned into an abstract syntax tree.
When the parser hits something illegal, it complains. That complaint may be called ParseError, ParserError, JSONDecodeError, or SyntaxError. Annoying? Yes. Useful? Also yes.
Honestly, it feels like the parser is yelling over one tiny typo. But that tiny typo can poison the whole result.
Common Python parse errors
The name depends on the library. Here are the usual suspects.
xml.etree.ElementTree.ParseError: XML is broken.json.JSONDecodeError: JSON is not valid.pandas.errors.ParserError: CSV or table data has bad rows.SyntaxError: Python code itself is not valid.yaml.YAMLError: YAML spacing or format is wrong.
A classic XML error looks like this:
xml.etree.ElementTree.ParseError:
mismatched tag: line 42, column 12
That means the parser saw a closing tag that did not match the last opening tag. Think of it like socks. One red sock. One blue sock. Python refuses the pair.
Fast troubleshooting checklist
Start here before rewriting your whole import script. Future you will be grateful.
- Read the full error. Do not stop at the first word.
- Find the line and column. Most parsers tell you where they choked.
- Print the bad snippet. Show 5 lines before and after the error.
- Check encoding. Use
utf-8when possible. - Check file completeness. Half-downloaded files are chaos.
- Validate the file. Use a JSON, XML, or CSV validator.
- Test with a tiny sample. Ten rows are easier than ten million.
It drives me crazy that a file can look fine in a text editor and still fail. Hidden characters are sneaky little gremlins.
XML ParseError: the fussy one
XML is strict. It wants every tag closed. It wants nesting to be clean. It wants special characters escaped.
This breaks:
<user>
<name>Sam & Lee</name>
</user>
The & must be written as &.
This works:
<user>
<name>Sam & Lee</name>
</user>
For XML, try this:
- Use
ElementTreefor clean, simple XML. - Use
lxmlfor faster parsing and better tools. - Use recovery mode only when you accept imperfect data.
JSON errors: strict but friendly
JSON is simpler than XML, but still strict. It hates trailing commas. It wants double quotes. It does not accept comments.
This fails:
{
"name": "Mia",
"age": 31,
}
That last comma is the villain.
Use json.loads() for valid JSON. If the data comes from logs or humans, consider jsonlines, orjson, or a cleanup step before parsing.
CSV and pandas ParserError: the messy cousin
CSV looks simple. It is not. Quotes go missing. Delimiters change. A note field may contain commas. Some rows have 12 columns. Others have 13. Great. Lovely.
A pandas error may say:
ParserError: Error tokenizing data.
Expected 8 fields in line 104, saw 10
That means row 104 has extra separators. Maybe a quoted field broke. Maybe someone pasted a comment into a spreadsheet cell.
Useful pandas options include:
sep=";"if the delimiter is not a comma.encoding="utf-8"orencoding="latin1".on_bad_lines="skip"for rough imports.engine="python"for more flexible parsing.quotechar='"'when quoted text contains commas.
Troubleshooting vs switching tools
Do not change tools too early. First ask one blunt question: Is the data supposed to be valid?
If yes, fix the source. Bad XML from an API is an API bug. Invalid JSON from your app is your app bug. Corrupt CSV from an export may mean the export settings are wrong.
If no, pick a parser that allows mess. Logs, scraped pages, old reports, and user uploads are rarely clean. Expect dents.
Parser alternatives by job
Use the right tool for the shape of the data.
- XML:
lxmlfor speed, XPath, and recovery options. - HTML:
BeautifulSoupfor broken web pages. - JSON:
orjsonfor speed,jsonfor standard use. - CSV:
pandasfor analysis,csvfor basic reads. - Huge files:
polars,pyarrow, or streaming parsers. - YAML:
ruamel.yamlwhen comments and formatting matter. - Web data:
BeautifulSoupplus cleanup rules.
For big data files, pandas can be heavy. A 2 GB CSV may make your laptop sound like a jet. Try polars or pyarrow. They often read large files faster and use memory more carefully.
Data processing alternatives
Sometimes parsing is only step one. You may need cleaning, checks, joins, and exports. In that case, use a data processing tool, not just a parser.
- pandas: Great for medium data and quick analysis.
- polars: Fast for larger tables.
- PyArrow: Strong for column data and Parquet files.
- Dask: Useful when data is bigger than memory.
- DuckDB: SQL on files. Very handy.
- Spark: Large cluster jobs, not small scripts.
If your script spends 90 seconds loading data and 2 seconds analyzing it, the parser is your bottleneck. If your file fails once a week because one supplier sends weird rows, validation is your bottleneck.
A small user case
A retail team imports product feeds from 12 vendors. Each vendor sends CSV files. Sounds easy. It was not.
Three vendors used commas. Four used semicolons. Two sent Latin-1 encoding. One added notes with unescaped quotes. The old script failed on 1 in 5 uploads.
The fix was boring but powerful:
- Detect encoding first.
- Detect delimiter from a sample.
- Log bad rows to a separate file.
- Use pandas for normal files.
- Use polars for files over 500 MB.
Failures dropped from 20% to 3%. The team did not need magic. They needed rules.
Best habits to prevent parse pain
- Validate before parsing. Catch junk early.
- Log the filename and row number. Guessing is misery.
- Save rejected rows. Do not throw them away.
- Use schemas. Define expected columns and types.
- Test ugly samples. Include empty files and weird characters.
- Separate parsing from cleaning. Keep code easier to fix.
Simple rule of thumb
If one file fails once, troubleshoot the file. If many files fail often, improve the pipeline. If the parser keeps fighting normal data, choose another parser.
Parse errors are not random monsters. They are clues. Follow the line number. Check the format. Clean the input. Then pick better tools when the data keeps acting like a raccoon in a keyboard factory.


