Unexpected Token in JSON: How to Fix This Common Error
The "Unexpected token" error is one of the most informative JSON parse errors — it explicitly tells you which character the parser found at the position where it expected something else. With the right debugging strategy, you can resolve this error in seconds. This comprehensive guide covers every common cause of unexpected token errors across JavaScript, Python, Java, and Go, with detailed debugging strategies. Use our JSON Validator for instant diagnosis.
What Does "Unexpected Token" Mean?
JSON parsers are state machines that expect specific tokens at each position. When parsing {"name": "Alice"}, after seeing {, the parser expects a property name (a double-quoted string). If it finds something else — a single quote, a number, an unquoted word, or a stray character — it throws an "unexpected token" error specifying the offending character and position. Our JSON Syntax Checker highlights these errors visually in your JSON document.
Complete Unexpected Token Reference
| Error Message | Likely Cause | Root Problem | Quick Fix |
|---|---|---|---|
Unexpected token '}' | Extra closing brace | Mismatched brackets from deletion without cleanup | Count opening vs closing braces; remove extra } |
Unexpected token ']' | Extra closing bracket | Array bracket mismatch | Remove extra ] |
Unexpected token 'h' | Unquoted string starting with 'h' | Using JavaScript-like unquoted keys or values | Wrap in double quotes: "hello" |
Unexpected token 'u' at position 0 | Response is literally "undefined" | JavaScript variable is undefined, passed to JSON.parse() | Check the value is not undefined before parsing |
Unexpected token '<' | HTML returned instead of JSON | Server returned 404/500 page, redirect, or error page | Verify API URL and HTTP status code |
Unexpected token 'N' | NaN value in JSON | JavaScript number operation produced NaN | Replace NaN with null |
Unexpected token '/' | Comment in JSON | JSON does not support // or /* */ comments | Remove comments or use JSONC format |
Unexpected token 'I' | Infinity value | JavaScript infinity value in JSON | Replace Infinity with null |
Debugging Unexpected Token Errors by Language
JavaScript
function debugJSONParse(text) {
try {
return JSON.parse(text);
} catch (e) {
if (e instanceof SyntaxError) {
const match = e.message.match(/position (d+)/);
const pos = match ? parseInt(match[1]) : 0;
const start = Math.max(0, pos - 20);
const end = Math.min(text.length, pos + 20);
console.error("Error near position", pos, ":");
console.error(text.substring(start, end));
console.error(" ".repeat(pos - start) + "^");
if (text.startsWith("<")) console.error("Got HTML instead of JSON");
if (text === "undefined" || text === "") console.error("Empty/undefined response");
}
return null;
}
}
Python
import json
def safe_parse(json_string):
try:
return json.loads(json_string)
except json.JSONDecodeError as e:
print(f"Error at line {e.lineno}, col {e.colno} (pos {e.pos})")
start = max(0, e.pos - 20)
end = min(len(json_string), e.pos + 20)
print(f"Context: ...{json_string[start:end]}...")
if json_string.strip().startswith("<"):
print("Response appears to be HTML, not JSON")
return None
Java (Jackson)
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
public JsonNode safeParse(String json) {
try {
return new ObjectMapper().readTree(json);
} catch (JsonParseException e) {
JsonLocation loc = e.getLocation();
System.err.printf("Error at line %d, col %d (byte offset %d)%n",
loc.getLineNr(), loc.getColumnNr(), loc.getCharOffset());
int pos = (int)loc.getCharOffset();
int start = Math.max(0, pos - 30);
int end = Math.min(json.length(), pos + 30);
System.err.println("Context: " + json.substring(start, end));
return null;
}
}
Step-by-Step Debugging Strategy
- Paste into validator — Use our JSON Validator to see the exact error position with clear highlighting
- Read the character — The error message includes the unexpected character.
<means HTML, a letter means unquoted text, punctuation means extra/missing brackets - Check context — Look at 20 characters around the reported position. The actual mistake is often just before the reported position
- Verify content type — If you got HTML, check the API URL, HTTP status, and
Content-Typeheader - Handle empty responses — Never parse empty strings, undefined, or null. Check the value before parsing
- Use automated repair — Our JSON Repair can fix many common issues automatically
Advanced Edge Cases
- BOM characters — UTF-8 BOM (U+FEFF) at the start of a file causes "Unexpected token" errors. Strip BOM before parsing
- Zero-width characters — Zero-width space (U+200B), zero-width non-joiner (U+200C), and other invisible characters cause baffling errors. Often introduced by copying from web pages
- Control characters — ASCII control codes (0x00-0x1F) except tab are not valid in JSON strings unescaped. Look for these in scraped or generated data
- Mixed encoding — When a file contains text in multiple encodings, some characters become garbled. Always save JSON as UTF-8 without BOM
- Truncated data — If the error occurs at the end of input, the JSON was cut off during transmission. Check content-length headers
Preventing Unexpected Token Errors in Production
- Always wrap
JSON.parse()in try/catch with meaningful error messages - Log the raw response text when errors occur for debugging
- Implement proper error boundaries in your application
- Validate JSON structure with our JSON Linter before processing
- Use schema validation with JSON Schema Validator for structural correctness
- Set up monitoring for JSON parse errors in production to catch issues early
Next Steps
Use our free JSON Validator to catch unexpected token errors instantly. For automated fixes, bookmark JSON Repair. For team-wide standards, add JSON Linter to your CI pipeline.