JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Updated by John Marshall
Python raises this when json.loads(), json.load(), or response.json() goes looking for a JSON value and finds something else. At line 1 column 1 (char 0), it failed on the very first character. That almost always means the text is empty, or it isn’t JSON at all. The usual culprit is an HTML error page. So before you go hunting for a typo, look at what you actually received.
Quick fix
- Print what you’re parsing:
print(repr(response.text[:200])). - If it’s empty or starts with
<, the request went wrong. Check the status code, the URL, and your credentials. - If it’s JSON with a mistake further in, paste it below to fix it.
Fix your JSON
Check what the API sent back
Most of the time, this error comes from an API call. Print the status code and the start of the body before you parse it:
response = requests.get(url, timeout=10)
print(response.status_code, response.headers.get("Content-Type"))
print(repr(response.text[:200]))What you see usually points straight at the cause:
'', an empty body. The server answered without any content, as with a204 No Contentresponse, or with an error it didn’t bother to describe.'<!DOCTYPE html>…', a web page. You got a 404 from a wrong URL, a login page because your token is missing or expired, a 403 from a firewall, or a 502 from a proxy. More on why servers send HTML.- Plain text, such as
Internal Server Error. The server crashed and sent its error message as text.
In every one of these cases, the fix is in the request, not the JSON. Once you’ve sorted it, it’s worth making your code fail with a clearer message next time:
response = requests.get(url, timeout=10)
response.raise_for_status()
if "application/json" not in response.headers.get("Content-Type", ""):
raise ValueError(f"Expected JSON, got: {response.text[:200]!r}")
data = response.json()Reading a JSON file
When the JSON comes from a file, the usual reason is that Python is reading nothing. If you’ve already called f.read(), the file is at its end, so a second json.load(f) gets an empty string. Parse the text you already read, or call f.seek(0) first. Also check how you opened the file: open(path, "w") empties it straight away, so open it with "r" to read it.
Another common slip is passing the file name to json.loads(). It parses the string you give it, so json.loads("settings.json") tries to read the letters settings.json as JSON and fails at char 0. Open the file and use json.load(f), without the s, which reads the file for you.
Files that start with a byte order mark
Some Windows programs save UTF-8 files with an invisible byte order mark at the start. Python then fails at char 0 with a slightly different message, Unexpected UTF-8 BOM (decode using utf-8-sig). The message already tells you the fix: open the file with the utf-8-sig encoding, which works whether or not the mark is there.
with open("settings.json", encoding="utf-8-sig") as f:
settings = json.load(f)When the error is further into the text
If the line or column isn’t 1, you do have JSON, but one value in it is broken. Python expected a value at that spot, and found something else. For example, {"a": ,} fails at column 7, where the value is missing. The usual suspects:
- A missing value, as in
"owner": , - A string in single quotes, such as
'active' - A trailing comma in an array, such as
[1, 2,] True,False, orNone. These mean the data was written withstr()orprint()instead ofjson.dumps().
The fixer above repairs all of these. In a large file, you can also print the text around error.pos to see exactly what Python tripped over:
try:
data = json.loads(text)
except json.JSONDecodeError as error:
print(f"line {error.lineno}, column {error.colno}")
print(text[max(0, error.pos - 40):error.pos + 40])The same error elsewhere
| json.loads, json.load | json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) |
|---|---|
| requests | requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) |
| Rust (serde_json) | expected value at line 1 column 1 |
| JavaScript, same input | Unexpected end of JSON input, or Unexpected token '<' |
| Go, same input | unexpected end of JSON input, or invalid character '<' looking for beginning of value |