Extra data: line 1 column N (char N)

json.loads parses exactly one JSON value. This message means it parsed one successfully and then found more text afterwards — so the document is not malformed so much as it is two documents. The offset is where the second one begins.

How the message appears

CPython's json module reports line, column and character offset. Here the offset is where the second document starts, which is the most useful number on this page.

  • json.decoder.JSONDecodeError: Extra data: line 1 column 25 (char 24)
  • json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 25)

What causes it

It is JSON Lines, not JSON

One complete JSON object per line, no commas, no enclosing array. .jsonl and .ndjson files are deliberately this shape, and so is the output of most log pipelines and many streaming APIs. It is not broken; it needs a different reader.

A file that was appended to

A script that opens with mode a and calls json.dump on each run produces a file with several documents stacked in it. Each one is valid; the file as a whole is not a single value.

Two responses concatenated

A proxy or a retry that wrote both bodies to the same buffer. The offset lands exactly where the second { starts, which is how you tell this apart from a syntax error inside one document.

The fix

Decide which format you actually have. For JSON Lines, parse each line on its own: [json.loads(line) for line in f if line.strip()]. For a single document, wrap the values in [ ] and separate them with commas, as the fixed sample shows.

Fails to parse
{"id": 1, "name": "Ada"}
{"id": 2, "name": "Grace"}
Parses
[
  {"id": 1, "name": "Ada"},
  {"id": 2, "name": "Grace"}
]

The example travels in the URL fragment, which browsers never send to a server.

Worth knowing

  • Do not convert a .jsonl file into an array without checking what reads it. JSON Lines exists so a huge file can be streamed one record at a time without holding it all in memory — turning it into an array throws that away.
  • json.JSONDecoder().raw_decode(text) parses one value and returns the index it stopped at, which is the supported way to walk a stream of concatenated documents.

Your JSON and text are processed entirely in your browser and are never sent anywhere. To understand how the site is used we record each page view — the page, the referrer and an approximate location from your IP address — and keep it for 90 days. Nothing is stored on your device unless you choose it. Accept to also store a device identifier here and record your browser and device characteristics, which is what lets a return visit be told from a new one. Decline and nothing is sent at all. We respect Do Not Track. See our privacy policy.