JSON escaping is required when a string contains quotes, backslashes, tabs, or line breaks that would otherwise make the payload invalid. If you are seeing errors like bad control character, unexpected token, or string cannot contain unescaped newline, this guide explains how JSON escape and unescape work, when to use each one, and how to fix broken strings safely. You can also test examples with our JSON validator and formatter to confirm the output is valid.
Why JSON Escaping Matters
JSON strings are delimited by double quotes. Any character inside a string that has special meaning in JSON or that could break the string must be escaped with a backslash (\). Failing to escape these characters leads to:
- Parse errors JSON.parse() throws a SyntaxError
- Data truncation String ends prematurely at an unescaped quote
- Security issues Unescaped content in HTML contexts enables XSS attacks
- API rejections Remote servers refuse malformed payloads
The Complete JSON Escape Sequence Table
The JSON specification (RFC 8259) defines exactly eight escape sequences:
| Character | Escape Sequence | Description |
|---|---|---|
" | \" | Double quote |
\ | \\ | Backslash (reverse solidus) |
/ | \/ | Forward slash (optional) |
| Backspace | \b | Control character U+0008 |
| Form feed | \f | Control character U+000C |
| Newline | \n | Line feed U+000A |
| Carriage return | \r | Carriage return U+000D |
| Tab | \t | Horizontal tab U+0009 |
| Unicode | \uXXXX | Any Unicode code point (4 hex digits) |
Most Common Escaping Mistakes
1. Unescaped Double Quotes
This is the #1 cause of JSON parse errors:
// WRONG the string ends at the second "
{ "message": "He said "hello" to me" }
// CORRECT double quotes inside strings must be escaped
{ "message": "He said \"hello\" to me" }
2. Literal Newlines in Strings
JSON strings cannot contain actual newline characters they must be escaped:
// WRONG literal newline breaks JSON
{
"description": "Line one
Line two"
}
// CORRECT use \n escape sequence
{ "description": "Line one\nLine two" }
3. Unescaped Backslashes
Windows file paths are a common trap:
// WRONG single backslash is an escape character
{ "path": "C:\Users\john\documents" }
// CORRECT each backslash must be doubled
{ "path": "C:\\Users\\john\\documents" }
4. Control Characters
Control characters (U+0000 to U+001F) are forbidden in JSON strings unless escaped:
// WRONG null byte and other control chars are invalid
{ "data": "Hello\x00World" }
// CORRECT use Unicode escape sequences
{ "data": "Hello\u0000World" }
Escaping in JavaScript
JSON.stringify() handles escaping automatically always use it instead of building JSON strings manually:
// Let JSON.stringify do the work
const obj = {
message: 'He said "hello"\nNew line here',
path: 'C:\\Users\\john',
tab: 'col1\tcol2'
};
const json = JSON.stringify(obj);
console.log(json);
// {"message":"He said \"hello\"\nNew line here","path":"C:\\Users\\john","tab":"col1\tcol2"}
// Unescape: JSON.parse reverses the process
const parsed = JSON.parse(json);
console.log(parsed.message); // He said "hello"
// New line here
Escaping for HTML Contexts
When embedding JSON in an HTML <script> tag, you also need to escape HTML special characters to prevent XSS:
// Dangerous script tag ends prematurely
const data = JSON.stringify({ html: "</script><script>alert(1)</script>" });
// Safe escape forward slashes in JSON embedded in HTML
const safe = JSON.stringify(data).replace(/\//g, '\\/');
// Or use a dedicated HTML-safe JSON serializer
Escaping in Python
Python's json module handles escaping correctly out of the box:
import json
data = {
"message": 'He said "hello"\nNew line',
"path": r"C:\Users\john",
"unicode": "Emoji: \U0001F600"
}
# Serialize escaping is automatic
json_str = json.dumps(data)
print(json_str)
# {"message": "He said \"hello\"\nNew line", "path": "C:\\Users\\john", "unicode": "Emoji: \ud83d\ude00"}
# Deserialize unescaping is automatic
parsed = json.loads(json_str)
print(parsed["message"]) # He said "hello"
# New line
# Preserve Unicode characters (don't escape them)
json_str = json.dumps(data, ensure_ascii=False)
# {"message": "He said \"hello\"\nNew line", ..., "unicode": "Emoji: ð"}
Nested JSON Strings
Nested JSON (JSON encoded as a string value within JSON) requires double-escaping one of the trickiest scenarios:
// Inner JSON object
const innerObj = { "key": "value with \"quotes\"" };
// Serialize inner object to string
const innerStr = JSON.stringify(innerObj);
// {"key":"value with \"quotes\""}
// Embed as a string value in outer JSON stringify again
const outer = JSON.stringify({ "payload": innerStr });
// {"payload":"{\"key\":\"value with \\\"quotes\\\"\"}"}
// Parse outer, then parse inner
const parsedOuter = JSON.parse(outer);
const parsedInner = JSON.parse(parsedOuter.payload);
console.log(parsedInner.key); // value with "quotes"
This pattern is common in webhook payloads, event systems (like AWS SNS/SQS), and API gateways that wrap payloads as JSON strings.
Unicode Escaping
Any Unicode character can be expressed as \uXXXX. For characters outside the Basic Multilingual Plane (code points above U+FFFF), JSON uses UTF-16 surrogate pairs:
// Basic Unicode emoji U+1F600 (ð) as surrogate pair
{ "emoji": "\uD83D\uDE00" }
// Python: json.dumps uses \uXXXX by default
import json
print(json.dumps({"emoji": "ð"}))
# {"emoji": "\ud83d\ude00"}
// To keep Unicode characters readable, use ensure_ascii=False
print(json.dumps({"emoji": "ð"}, ensure_ascii=False))
# {"emoji": "ð"}
Unescape JSON: Common Use Cases
Unescaping converts escaped sequences back to their original characters. You'll need this when:
- Reading a JSON string stored in a database that was double-escaped
- Debugging API responses that contain stringified JSON payloads
- Processing log files where JSON was serialized as a string
- Working with AWS Lambda events, Kafka messages, or message queues
// JavaScript: unescape a JSON string
const escaped = '{"message":"Hello\\nWorld","path":"C:\\\\Users\\\\john"}';
const unescaped = JSON.parse(escaped);
console.log(unescaped.message); // Hello
// World
console.log(unescaped.path); // C:\Users\john
// Python: unescape
import json
escaped = '{"message": "Hello\\nWorld", "path": "C:\\\\Users\\\\john"}'
parsed = json.loads(escaped)
print(parsed["message"]) # Hello
# World
Quick Reference: Escape Sequences You Need Daily
| You want to store /th> | Write in JSON as /th> |
|---|---|
A double-quote character " | \" |
A backslash \ | \\ |
| A newline (line break) | \n |
| A tab character | \t |
A Windows path C:\Users | C:\\Users |
| Emoji ð (U+1F600) | \uD83D\uDE00 or literal if allowed |
| Null byte (U+0000) | \u0000 |
Key Takeaways
- Always use a JSON library (
JSON.stringify,json.dumps) to serialize never build JSON strings by hand - The eight mandatory escape sequences:
\"\\\/\b\f\n\r\t - Control characters (U+0000–U+001F) must always be escaped
- Nested JSON requires double-escaping use
JSON.parsetwice to unwrap - Use an online tool to quickly escape/unescape strings when debugging
Frequently Asked Questions
What does it mean to escape JSON?
Escaping JSON means replacing special characters inside a string, such as " or \n, with valid escaped versions so the JSON parser can read them correctly.
How do I fix an unescaped newline in JSON?
Replace the raw line break inside the string with \n, or re-encode the string using a JSON-safe serializer before sending or storing it.
What is the difference between escape and unescape in JSON?
Escaping turns special characters into JSON-safe sequences, while unescaping converts those sequences back into readable text.