{}JSON FYI

Python JSONDecodeError — json.loads() error causes and fixes

Everything you need to diagnose a Python json.loads() or json.load() failure: error attributes, the six most common causes, and code fixes for each.

·6 min read

When Python's json.loads() or json.load() fails, it raises a json.JSONDecodeError. This exception is a subclass of ValueError and carries three useful attributes: msg (what went wrong), doc (the input string), and pos (byte offset of the error).

Reading the error

import json

try:
    data = json.loads(s)
except json.JSONDecodeError as e:
    print(f"Error:  {e.msg}")
    print(f"At:     line {e.lineno}, col {e.colno} (char {e.pos})")
    print(f"Around: {e.doc[max(0,e.pos-20):e.pos+20]!r}")

The six most common causes

1. Trailing comma

json.loads('{"a": 1, "b": 2,}')
# JSONDecodeError: Expecting property name enclosed in double quotes

2. Single-quoted strings

json.loads("{'name': 'Ada'}")
# JSONDecodeError: Expecting value

3. Python literals instead of JSON

json.loads("{'ok': True, 'x': None}")
# JSONDecodeError: Expecting value
# Fix: json.dumps(python_dict) converts True→true, None→null automatically

4. Reading a file opened in binary mode

# ✗ binary mode — json.load() expects text, not bytes
with open('data.json', 'rb') as f:
    data = json.load(f)

# ✓ text mode with explicit encoding
with open('data.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

5. Extra content after the root value

json.loads('{"a": 1}
{"b": 2}')
# JSONDecodeError: Extra data
# Use json.JSONDecoder().raw_decode() or process line-by-line for NDJSON

6. Response body not yet decoded

import requests
r = requests.get(url)
# ✗ r.content is bytes, not str
data = json.loads(r.content)  # may fail on encoding issues

# ✓ use r.json() which handles encoding
data = r.json()
# ✓ or decode explicitly
data = json.loads(r.content.decode('utf-8'))

Convert Python dict to JSON safely

import json

python_dict = {"ok": True, "data": None, "items": [1, 2, 3]}
json_str = json.dumps(python_dict)  # ✓ True→true, None→null
data_back = json.loads(json_str)    # ✓ round-trips correctly

Paste your JSON into the validator →

Get the exact line, column, and a fix hint in seconds — no upload, no signup.

Open JSON Validator →

Frequently asked questions

Is JSONDecodeError the same as ValueError?+

Yes — json.JSONDecodeError inherits from ValueError. You can catch it with 'except ValueError' too, but catching the specific JSONDecodeError gives you access to the lineno, colno, and pos attributes.

How do I parse a file that contains one JSON object per line (NDJSON)?+

Use a loop: for line in f: data = json.loads(line.strip()). The standard json module parses one JSON value per call, so you must split the file into lines first.

My JSON is valid in an online validator but json.loads() still fails — why?+

Check the file's encoding. If the file has a UTF-8 BOM (starts with \xef\xbb\xbf), open it with encoding='utf-8-sig' instead of 'utf-8'. Also check for Windows CRLF line endings inside strings.

Related tools & guides