json.decoder.JSONDecodeError: Extra data: line 1 column N (char N)

Quick answer

Python parsed one valid JSON value and then found more content after it. json.loads() expects exactly one JSON document, so the leftover text raises Extra data. The most common cause is having multiple JSON objects in one string or file — usually JSON Lines (NDJSON). Parse each object separately instead of the whole blob at once.

The exact error string

The traceback ends with a line like this (the column and char index vary with your input):

Traceback (most recent call last):
  File "app.py", line 5, in <module>
    data = json.loads(text)
json.decoder.JSONDecodeError: Extra data: line 1 column 14 (char 13)

You may also see it raised through the requests library as requests.exceptions.JSONDecodeError or from response.json() — both wrap the same underlying json.decoder.JSONDecodeError.

What “line 1 column N (char N)” means

The number in parentheses is the character index where parsing stopped being happy. For Extra data, that index is the first character after a complete, valid JSON value. In char 13, the parser read a full value across the first 13 characters, then hit something it did not expect at index 13.

This is the opposite of Expecting value: line 1 column 1 (char 0), which fails at the very start. With Extra data, the beginning is valid JSON — the problem is that there is more than one value.

Here is exactly where the parser gives up on {"id":1}{"id":2}:

Valid — one JSON value, parsed cleanly:
{"id":1}

Invalid — two values with nothing between them:
{"id":1}{"id":2}
        ^
        char 8 (column 9) — the first value ended at the } just
        before here, so everything from this point on is "Extra data".

Note the off-by-one between the two numbers: char is 0-based (the 9th character is index 8), while column is 1-based. They point at the same spot — the first character the parser did not expect.

Cause 1: Two or more JSON objects in one string

The classic trigger. Two objects concatenated — even separated by a newline — are not a single JSON document:

import json

text = '{"id": 1}\n{"id": 2}'   # two objects, not one
data = json.loads(text)          # JSONDecodeError: Extra data: line 2 column 1 (char 10)

json.loads() parses the first {"id": 1}, then finds a second object where it expected the end of the string.

Cause 2: JSON Lines / NDJSON parsed all at once

Log files, bulk exports, and many streaming APIs use JSON Lines (also called NDJSON): one JSON object per line. Passing the whole file to json.loads() always fails:

import json

with open("events.jsonl") as f:
    data = json.loads(f.read())   # Extra data at the end of the first line

Each line is its own document. The fix is to parse line by line (see below). If you are unsure whether your data is JSON or JSON Lines, the difference is covered in JSON vs JSONL.

Cause 3: Trailing content after a valid value

Sometimes the body is a single object with stray characters appended — a duplicated write, a leftover comma, a second print, or two responses glued together:

import json

text = '{"ok": true}garbage'     # trailing junk
json.loads(text)                  # Extra data: line 1 column 13 (char 12)

text = '{"a": 1},'                # leftover trailing comma after the object
json.loads(text)                  # Extra data: line 1 column 9 (char 8)

Cause 4: Appending to a JSON file

Opening a .json file in append mode ("a") and writing another object produces two top-level values in one file. Later, json.load() reads the first and reports Extra data on the second. For multiple records, write a JSON array or switch to JSON Lines deliberately.

Extra data vs other JSONDecodeError messages

Python's json module raises a different message for each kind of problem. If the wording in your traceback is not Extra data, match it here and jump straight to the fix:

Error messageUsually means
Extra dataMore than one JSON value in the string — this page
Expecting valueAn empty string or non-JSON content (often an HTML error page)
Expecting property name enclosed in double quotesSingle quotes, or a trailing comma before a key
Expecting ',' delimiterA missing comma between two array items or object members
Unterminated string starting atA string is missing its closing double quote
Invalid control character atA raw newline or tab inside a string that should be escaped

How to debug it

Print the raw content so you can see the boundary the parser tripped on. repr() reveals newlines and hidden characters a plain print() hides:

import json

text = open("data.json").read()
print(repr(text[:200]))           # see exactly what follows the first value

try:
    json.loads(text)
except json.JSONDecodeError as e:
    print("failed at char", e.pos)         # the boundary index
    print("context:", repr(text[e.pos-5:e.pos+5]))

The fix: parse the right number of values

If the source is JSON Lines, loop over the lines and parse each one:

import json

records = []
with open("events.jsonl") as f:
    for line in f:
        line = line.strip()
        if not line:
            continue              # skip blank lines
        records.append(json.loads(line))

If you have a stream of concatenated values with no newline separators, use raw_decode() to read them one at a time:

import json

def iter_json(text):
    decoder = json.JSONDecoder()
    idx = 0
    while idx < len(text):
        text = text[idx:].lstrip()
        if not text:
            break
        obj, end = decoder.raw_decode(text)
        yield obj
        idx = end

for obj in iter_json('{"id": 1}{"id": 2}'):
    print(obj)

If it is supposed to be one value, fix the producer so it emits a single JSON document — wrap multiple records in an array [ {...}, {...} ] rather than concatenating them.

Not sure if it is one JSON value or several?

Paste the body into the validator — it pinpoints exactly where the first value ends and the extra data begins. Everything runs in your browser; nothing is uploaded.

JSON Validator JSON Formatter

Frequently Asked Questions

What does JSONDecodeError: Extra data mean?

It means Python's json module parsed one complete JSON value, then found more non-whitespace characters after it. json.loads() expects exactly one JSON document. The position in the message — for example char 13 — points to the first character after the first valid value, which is where the unexpected extra content begins. Most often you actually have two or more JSON objects in the same string or file.

How do I fix Extra data: line 1 column N (char N)?

Decide what the source really contains. If it is several JSON objects separated by newlines (JSON Lines / NDJSON), parse each line separately with json.loads() in a loop instead of parsing the whole file at once. If it is one object with trailing junk, fix or strip the trailing content at the source. If you genuinely have a stream of concatenated values, use json.JSONDecoder().raw_decode() to read them one at a time.

How do I parse JSON Lines (NDJSON) in Python?

Read the file line by line and call json.loads() on each line: open the file, iterate over its lines, skip blank lines, and parse each one into its own object. Do not pass the whole file to json.loads() — that is what triggers Extra data, because each line is a separate JSON document, not one big value.

Why does response.json() raise Extra data?

Because the response body contains more than one JSON document. Some streaming and bulk APIs return newline-delimited JSON (one object per line) or server-sent events, not a single JSON array. response.json() calls json.loads() on the entire body and fails at the boundary between the first and second value. Inspect response.text first, and if it is line-delimited, parse each line individually.

What is the difference between Extra data and Expecting value?

Expecting value: line 1 column 1 (char 0) fails at the very start — the content is empty or not JSON at all. Extra data fails after a complete, valid JSON value — the start was fine, but there is leftover content the parser did not expect. Extra data almost always means multiple values in one string; Expecting value almost always means an empty body or an HTML error page.

About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.