jsonerrorsdebuggingapijavascript

Unexpected End of JSON Input — Causes and Fixes

·8 min read·Error Fixes

What Is "Unexpected End of JSON Input"?

This JavaScript error from JSON.parse() means the input string ended before the JSON structure was complete. The parser was in the middle of reading an object, array, or string value and ran out of characters unexpectedly.

SyntaxError: Unexpected end of JSON input

In Python the equivalent is: json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

In Go: unexpected end of JSON input from json.Unmarshal

Common Causes

Cause 1: Empty Response Body (Most Common)

Your server or API returned an empty response body — a 204 No Content, a 200 OK with no body, or a DELETE response. Calling .json() on an empty body always throws:

javascript
// Throws if body is empty:
const data = await response.json();

// Safe version:
const text = await response.text();
const data = text.trim() ? JSON.parse(text) : null;

Cause 2: Truncated JSON from Network Issues

The response was cut off mid-transfer — network timeout, server crash during streaming, or a proxy with a small body size limit. The JSON is valid up to the cut-off point but incomplete:

json
{"users": [{"name": "Ravi", "age": 28}, {"name": "Priy

The parser reaches end-of-string while inside a string literal and throws. Diagnosis: check Content-Length vs actual bytes received — a mismatch confirms truncation.

Cause 3: Parsing null or undefined

javascript
const raw = localStorage.getItem("session"); // returns null if key missing
JSON.parse(raw); // TypeError or SyntaxError: null is not valid JSON

const value = someObject.field; // undefined if field doesn't exist
JSON.parse(value); // SyntaxError

Always guard:

javascript
const raw = localStorage.getItem("session");
const data = raw !== null ? JSON.parse(raw) : defaultValue;

Cause 4: Empty String or Whitespace-Only String

javascript
JSON.parse("");    // SyntaxError: Unexpected end of JSON input
JSON.parse("   "); // same
JSON.parse("\n");  // same

The smallest valid JSON values are: null, 0, "", true, false, [], {}

Cause 5: Incomplete JSON File Written to Disk

If a write operation was interrupted — server crash, disk-full event, process killed with SIGKILL — the JSON file on disk may be incomplete. The file ends mid-structure:

{"config": {"host": "localhost", "port": 543

The file ends here — missing closing braces. The file is corrupt.

Check the last few bytes: a complete JSON object ends with }, a complete array ends with ]. If neither, the file is corrupt.

Cause 6: Content-Length Header Mismatch

The server sends a Content-Length header that is larger than the actual body. The HTTP client waits for the remaining bytes, times out, and returns a truncated body. Check in the Network tab — does the content-length match the actual received bytes?

Cause 7: Streaming Response Read Twice

In Node.js, once you call response.json() or response.text(), the body stream is consumed. Calling it again returns an empty body:

javascript
const response = await fetch(url);
const text = await response.text();    // consumes the body
const data = await response.json();    // throws — body already consumed

Fix: read the body once and parse manually:

javascript
const text = await response.text();
const data = JSON.parse(text);

Diagnosing Network Truncation

javascript
async function fetchJSON(url) {
  const response = await fetch(url);

  if (response.status === 204) return null; // No Content — expected empty body

  const text = await response.text();

  if (!text.trim()) {
    console.warn(`Empty body from ${url} (status: ${response.status})`);
    return null;
  }

  // Check Content-Length vs actual received bytes
  const contentLength = response.headers.get("content-length");
  if (contentLength && parseInt(contentLength) !== text.length) {
    console.warn(
      `Possible truncation: Content-Length=${contentLength}, received=${text.length} bytes`
    );
  }

  try {
    return JSON.parse(text);
  } catch (e) {
    console.error(`JSON parse error from ${url}:`, e.message);
    console.error(`Last 100 chars: ...${text.slice(-100)}`);
    throw e;
  }
}

Safe Parse Utilities

JavaScript:

javascript
function safeJSON(str, fallback = null) {
  if (str == null || !String(str).trim()) return fallback;
  try {
    return JSON.parse(str);
  } catch (e) {
    console.error("JSON parse failed:", e.message, "| Input:", String(str).slice(0, 100));
    return fallback;
  }
}

// localStorage pattern
function loadFromStorage(key, fallback = null) {
  try {
    const raw = localStorage.getItem(key);
    return raw !== null ? JSON.parse(raw) : fallback;
  } catch {
    localStorage.removeItem(key); // clear corrupted data
    return fallback;
  }
}

Python:

python
import json

def safe_json(text: str, fallback=None):
    if not text or not text.strip():
        return fallback
    try:
        return json.loads(text)
    except json.JSONDecodeError as e:
        print(f"JSON parse error: {e} | Input: {text[:100]!r}")
        return fallback

Go:

go
func safeUnmarshal(data []byte, v interface{}) error {
    if len(data) == 0 {
        return nil // empty body — treat as no data, not an error
    }
    if err := json.Unmarshal(data, v); err != nil {
        return fmt.Errorf("JSON parse failed: %w | last chars: %q",
            err, data[max(0, len(data)-50):])
    }
    return nil
}

When the JSON File on Disk Is Corrupt

  1. Check the last characters: tail -c 10 data.json
  2. Validate with python3 -c "import json; json.load(open('data.json'))"
  3. If corrupt, restore from backup or re-fetch from the source
  4. Add atomic write protection: write to a temp file then rename, so a crash mid-write never corrupts the original

Use JSONKit's JSON Validator to confirm that any JSON string you have is complete and valid before using it in your application.

Try JSON Validator

Find the missing bracket, brace or quote causing the truncation error.