Fix JSONDecodeError: Expecting Value at Line 1

Quick Answer

The decoder received an empty string, HTML, plain text, or otherwise invalid JSON at character zero. Check the response status, content type, and trimmed body before calling json.loads(); for a file, check that it exists and is not empty.

JSON response validation visual showing an API body checked before Python parsing
Validate status, content type, and body text before handing a response to Python’s JSON decoder.

JSONDecodeError: Expecting value: line 1 column 1 (char 0) means Python tried to parse JSON, but the first character did not start a valid JSON value. In practice, the input is often empty, HTML, a plain-text error message, or a file that was not written as JSON.

Python’s json module documentation explains json.loads(), json.load(), and JSONDecodeError. The fix is not to catch every error and move on. First inspect what you are actually passing into the JSON parser.

Reproduce the error

The smallest example is an empty string. There is no object, array, string, number, Boolean, or null value for the parser to read, so parsing fails at character position zero.

import json

try:
    data = json.loads("")
except json.JSONDecodeError as error:
    print(error)
    print(error.lineno, error.colno, error.pos)

The position data is useful. line 1 column 1 points to the start of the input. If the error points later in the file, you likely have a syntax problem after some valid JSON has already been read.

Python Pool infographic showing JSON text, bytes, object structure, parser, and decoder input
JSON input: JSON text, bytes, object structure, parser, and decoder input.

Check for empty API responses

Many API failures are not JSON parser problems. A server may return a 204 response, an empty body, or an HTML error page. Check the status code, content type, and body text before calling json.loads().

import json

class Response:
    status_code = 204
    headers = {"content-type": "application/json"}
    text = ""

response = Response()

if response.status_code == 204 or not response.text.strip():
    data = None
else:
    data = json.loads(response.text)

print(data)

For real HTTP clients, apply the same checks to the response object you receive. If the response is empty by design, do not parse it as JSON.

Check content type before parsing

Another common cause is receiving HTML while expecting JSON. A login page, proxy error, or rate-limit page may start with <html>, which is not a JSON value.

import json

headers = {"content-type": "text/html; charset=utf-8"}
body = "<html><title>Error</title></html>"

content_type = headers.get("content-type", "")
if "application/json" not in content_type:
    raise ValueError(f"Expected JSON, got {content_type}")

data = json.loads(body)
print(data)

This error message is more helpful than the raw decoder error because it tells you the upstream response was the wrong format. Log a short preview of the body when debugging, but avoid logging private payloads.

Python Pool infographic comparing empty response, HTML error page, malformed JSON, encoding, and content type
Decode causes: Empty response, HTML error page, malformed JSON, encoding, and content type.

Read JSON files safely

For files, check that the path exists and that the file is not empty before loading it. This separates file problems from JSON syntax problems.

import json
from pathlib import Path

path = Path("settings.json")

if not path.exists():
    raise FileNotFoundError(path)
if path.stat().st_size == 0:
    data = {}
else:
    with path.open(encoding="utf-8") as file:
        data = json.load(file)

print(data)

The check if a file exists guide covers file checks in more detail. If you are writing bytes or reading binary content before parsing, the byte-like object required guide may also help.

Show invalid JSON clearly

When the input is not empty, print a small preview and the decoder location. That usually reveals single quotes, trailing commas, comments, or other syntax that JSON does not allow.

import json

text = "{'name': 'Python Pool'}"

try:
    data = json.loads(text)
except json.JSONDecodeError as error:
    preview = text[max(error.pos - 20, 0):error.pos + 20]
    print(f"line={error.lineno} column={error.colno} pos={error.pos}")
    print(preview)

JSON requires double quotes around object keys and string values. Python dictionary syntax is similar, but it is not the same format. If you need to compare valid JSON files, see the jsondiff in Python guide.

Handle a UTF-8 byte order mark

Some files begin with a byte order mark. If that character appears at the start of the decoded text, it can confuse JSON parsing. Open the file with utf-8-sig to remove it while reading.

import json
from pathlib import Path

def load_json_with_sig(path):
    text = Path(path).read_text(encoding="utf-8-sig")
    if not text.strip():
        return None
    return json.loads(text)

sample = chr(0xFEFF) + '{"ok": true}'
print(json.loads(sample.lstrip(chr(0xFEFF))))

Use this only when you know files may include that marker. For ordinary UTF-8 JSON, encoding="utf-8" is enough.

Python Pool infographic mapping response status, content type, text validation, json.loads, and error handling
Decode safely: Response status, content type, text validation, json.loads, and error handling.

Create a safe helper

A small helper can handle the most common cases: empty input, wrong content type, and decoder errors with useful context. The helper should return a known fallback only for truly empty input. For malformed JSON, it should raise a clearer exception and keep the original JSONDecodeError as the cause.

This does not hide bad JSON. It gives the caller a clearer failure path and treats truly empty input as a known case. If you need optional imports around JSON-related packages, the Python conditional import guide shows safe import patterns.

Prevent the error

Preventing this error is mostly about boundaries. Do not parse a response until you know it succeeded. Do not parse a file until you know it exists and has content. Do not assume a command-line tool, web API, or cache wrote JSON just because the filename ends in .json. A small validation step before parsing saves a longer debugging session later.

Python Pool infographic testing empty body, whitespace, null, arrays, objects, and truncated JSON
Payload checks: Empty body, whitespace, null, arrays, objects, and truncated JSON.

Quick checklist

When you see line 1 column 1 char 0, check the raw text first. Is it empty? Is it HTML? Is it a server error? Is the content type JSON? Is the file path correct? Is the file blank? Is the text valid JSON with double quotes? Answer those questions before changing parser code.

The decoder error is a symptom. The fix is usually at the boundary where data is fetched, read, or written. Validate that boundary, then parse only when the input is actually JSON.

Inspect the Raw Input Without Logging Secrets

When debugging an API or file, inspect a short, redacted preview rather than printing a complete token or user payload. A body that starts with <html>, an empty string, or a proxy message points to an upstream problem rather than malformed JSON generated by Python.

def describe_body(body):
    preview = body.strip()[:120]
    return {"empty": not bool(preview), "preview": preview}

print(describe_body(response.text))

Once the input is confirmed to be JSON, parse it and handle JSONDecodeError at the boundary so the rest of the application receives a clear failure or a documented fallback.

Frequently Asked Questions

What does JSONDecodeError at line 1 column 1 mean?

Python found no valid JSON value at the start of the input. The body is commonly empty, HTML, plain text, or malformed before the first character.

Why does an API return JSONDecodeError when the endpoint looks correct?

The endpoint may return a login page, rate-limit page, server error, or 204 empty response. Check status_code, content-type, and response.text before parsing.

How do I handle an empty JSON file?

Check that the file exists and has non-whitespace content before json.load(). Decide whether an empty file is an error or should map to a documented default value.

Should I catch JSONDecodeError and ignore it?

No. Catch it at the input boundary, record a safe diagnostic, and either return a clear error or apply an intentional fallback. Ignoring it can hide an upstream outage.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted