json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Python’s json module wanted a JSON value (an object, array, string, number, true, false or null) and found something else. At line 1 column 1 (char 0) that means the very first character was wrong: the text is empty, or it is not JSON at all, like the proxy error page in this sample. At any other position, a value is missing or misspelled inside the document.

Seen as:

  • json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
  • requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
  • simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
  • json.decoder.JSONDecodeError: Expecting value: line 3 column 15 (char 36)

Input

Settings

History

Load from URL

Common causes

1. The HTTP response body is empty

A 204 reply, a failed request or a server that crashed before writing returns an empty body, and response.json() fails at char 0. Check the status and the body before decoding.

Before
resp = requests.get(url, timeout=10)
data = resp.json()
After
resp = requests.get(url, timeout=10)
resp.raise_for_status()
data = resp.json() if resp.content else None

2. The response is HTML or plain text, not JSON

Error pages from nginx, Cloudflare or an Envoy sidecar, login pages and rate-limit notices are not JSON. Check the content type and log the start of the body so the real problem is visible. See also Unexpected token ‘<’.

Before
data = resp.json()
After
if "application/json" not in resp.headers.get("Content-Type", ""):
    raise RuntimeError(f"{resp.status_code} from {resp.url}: {resp.text[:200]!r}")
data = resp.json()

3. json.loads given a file name instead of file contents

json.loads("config.json") tries to parse the eleven characters of the file name. Use json.load with an open file, or read the file first.

Before
config = json.loads("config.json")
After
with open("config.json", encoding="utf-8") as f:
    config = json.load(f)

4. The file was already read to the end

After f.read() the file position is at the end, so a following json.load(f) reads an empty string. Parse the text you already have, or f.seek(0) first.

Before
with open("data.json", encoding="utf-8") as f:
    print(f.read())
    data = json.load(f)
After
with open("data.json", encoding="utf-8") as f:
    text = f.read()
    print(text)
    data = json.loads(text)

5. A missing value inside the document

When the column is not 1, a value is missing or invalid at that spot: an empty slot after a colon, a trailing comma in an array, or a word like undefined or True.

Before
{"order_id": 1182, "discount": , "currency": "EUR"}
After
{"order_id": 1182, "discount": null, "currency": "EUR"}

Frequently asked questions

What does "char 0" mean?

It is the zero-based character offset of the problem, so char 0 is the very first character. Combined with line 1 column 1 it almost always means the input is empty or is not JSON at all.

Why does requests raise requests.exceptions.JSONDecodeError?

Since requests 2.27, response.json() wraps the decoder error in its own JSONDecodeError class, which is also a subclass of the standard one. The message and the cause are the same.

How do I see what Python actually received?

Print repr(resp.text[:500]) or repr(text[:500]) before decoding. repr shows an empty string as ‘’ and makes invisible characters such as a BOM or stray whitespace visible.

Related