Quick answer
json.loads() and json.load() raise json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) when the text is empty or when its first character cannot start a JSON value. Fix: print what you are really parsing with repr(text[:200]), then correct the source. The usual culprits are an empty response, an error page, a file name passed instead of file content, or a file that was already read.
What the message means
Expecting value means the parser wanted an object, array, string, number, true, false or null and found something else, or nothing at all. line 1 column 1 (char 0) says this happened at the very first character. If you see a larger position such as line 3 column 5, the start of the text is fine and the problem is later in the document. Look at that spot instead.
Example that fails
import json
json.loads("")
# json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
First step: see what you actually have
print(repr(text[:200])) # what the parser really sees
print(len(text)) # 0 means the text is empty
Common causes and fixes
1. The string or response body is empty
An API that returns 204 No Content, a failed download, or a variable that was never filled all give an empty string.
if not text.strip():
print("Nothing to parse")
else:
data = json.loads(text)
2. The server sent HTML or plain text instead of JSON
A 404 page, a 500 error or a login redirect starts with <!DOCTYPE html> or a plain message, so the first character is not valid JSON. With requests, check the status code and the raw text before calling .json().
import requests
r = requests.get("https://example.com/api/data", timeout=10)
print(r.status_code, r.headers.get("Content-Type"))
print(r.text[:200]) # HTML or empty text here explains the error
r.raise_for_status() # stop on 404 or 500 instead of parsing an error page
data = r.json()
The same problem in JavaScript appears as Unexpected token < in JSON at position 0.
3. A file name was passed instead of the file content
json.loads() parses text, not paths. Use json.load() with an open file.
json.loads("data.json") # wrong: this is a file name, not JSON text
with open("data.json", encoding="utf-8") as f:
data = json.load(f) # correct
4. The file was already read, or the file is empty
After f.read() the file pointer is at the end, so json.load(f) sees no text. A file that has zero bytes fails the same way.
with open("data.json", encoding="utf-8") as f:
raw = f.read()
data = json.load(f) # wrong: nothing left to read
with open("data.json", encoding="utf-8") as f:
raw = f.read()
data = json.loads(raw) # correct: parse the text you already have
Show exactly where parsing fails
try:
data = json.loads(text)
except json.JSONDecodeError as e:
print(e.msg, "line", e.lineno, "column", e.colno, "char", e.pos)
print(repr(text[max(0, e.pos - 20):e.pos + 20]))
If the text looks like real JSON but still fails, paste it into the JSON Formatter to see the error highlighted, or use the JSON Repair tool to fix common mistakes automatically.
Have broken JSON right now?
Paste it into the free JSON Repair tool. It runs in your browser, so nothing is uploaded.
Open JSON Repair toolFAQ
What does (char 0) mean?
It is the zero-based position of the character where the parser failed. Char 0 is the first character of the text, so the very start is already wrong or missing.
Why does response.json() in requests raise this error?
The response body is empty or is not JSON, often an HTML error page. Newer versions of requests raise their own requests.exceptions.JSONDecodeError with the same message. Check r.status_code and r.text first.
Is my JSON uploaded when I use Parsekit tools?
No. The tools run in your browser and nothing you paste is sent to a server.