JSON null vs undefined: What Happens When You Stringify undefined?

JSON has null. JSON does not have undefined. This single fact causes a class of bugs where fields silently vanish from API payloads, objects arrive with missing keys, or arrays gain unexpected null slots — and no error is ever thrown.

Inspecting a JSON payload with null values? Format and validate it instantly:

JSON Formatter → JSON Validator →

The six value types JSON defines

The JSON specification (RFC 8259) defines exactly six value types: string, number, boolean (true/false), null, object, and array. undefined is not on this list.

undefined is a JavaScript-specific primitive that means "a variable was declared but never assigned." Because JSON must be portable across every programming language, it can only carry concepts every language can represent. undefined has no equivalent in Python, Java, Go, or Rust — so it was intentionally excluded from the spec.

What JSON.stringify does with undefined

There are three different places an undefined can appear, and JSON.stringify handles each differently.

Case 1 — top-level undefined

JSON.stringify returns the JS primitive undefined — not the string "undefined", not "null", not an empty string. Nothing is serialised.

JSON.stringify(undefined);  // → undefined  (not a string!)
typeof JSON.stringify(undefined);  // → "undefined"

// This means it cannot be used as a fetch body:
const body = JSON.stringify(undefined);
console.log(body);  // undefined — nothing useful is sent

Case 2 — object property with an undefined value

The key is silently omitted from the output. No error, no warning. This is the most common source of bugs — a field is set to undefined expecting it to be included in a request body, but it never reaches the server.

const user = {
  name: "Alice",
  age: undefined,      // ← will be dropped
  role: "admin",
  token: undefined,    // ← will be dropped
};

JSON.stringify(user);
// → '{"name":"Alice","role":"admin"}'
// age and token are gone silently

Case 3 — array element is undefined

Array elements are replaced with null to preserve the array's indices. The length of the output array matches the original.

JSON.stringify([1, undefined, 3, undefined]);
// → '[1,null,3,null]'

// Also happens with holes in sparse arrays:
const sparse = [1,,3];
JSON.stringify(sparse);
// → '[1,null,3]'

Summary table

Location of undefinedJSON.stringify outputEffect
Top-level valueundefined (JS primitive)Nothing serialised
Object property valueKey omitted entirelySilent data loss
Array elementReplaced with nullLength preserved; value lost
Property returned by toJSON()Key omitted entirelySame as object property rule

null vs undefined in JavaScript

let a;           // declared but not assigned → undefined
let b = null;    // explicitly assigned "no value"

typeof a;  // "undefined"
typeof b;  // "object"  ← historical quirk of JS

a == b;    // true  (loose equality — both are "nothing")
a === b;   // false (strict equality — different types)

In JSON terms: null serialises cleanly to null; undefined triggers the silent-drop behaviour above.

What about JSON.parse?

JSON.parse can never produce undefined as a value — because undefined is not in the JSON spec. If the JSON text contains null, you get JavaScript null. If a key is simply absent, accessing it on the resulting object gives you JavaScript undefined (the language's default for missing keys), but that is not something JSON put there.

const parsed = JSON.parse('{"name":"Alice","age":null}');

parsed.age;       // null  ← JSON null, parsed as JS null
parsed.email;     // undefined ← key absent; JS default for missing keys

parsed.age === null;        // true
parsed.email === undefined; // true — but the key was never in the JSON

How to preserve undefined values — convert to null

If you want every key sent — even those currently undefined — convert them to null using a replacer function:

const user = {
  name: "Alice",
  age: undefined,
  role: "admin",
};

const json = JSON.stringify(user, (key, value) =>
  value === undefined ? null : value
);

console.log(json);
// → '{"name":"Alice","age":null,"role":"admin"}'
// All keys present; undefined replaced with null

The server now receives every field. It can distinguish "not provided" (null) from "field was removed from the schema" (key absent) — important for PATCH endpoints.

Detecting null vs missing key in parsed JSON

Once you have parsed a JSON payload, use key in obj — not obj[key] !== undefined — to tell whether a field was explicitly set to null or simply not sent:

const a = JSON.parse('{"name":"Alice","age":null}');
const b = JSON.parse('{"name":"Alice"}');

"age" in a;  // true  — key was sent, value is null
"age" in b;  // false — key was never included

a.age;  // null
b.age;  // undefined ← JS default, not from JSON

How other languages handle JSON null

LanguageJSON null maps toEquivalent of JS undefined
JavaScriptnullundefined (absent key)
PythonNoneNo equivalent — absent key raises KeyError
Java (Jackson)nullNo equivalent — absent key = default field value
Gonil (pointer/interface)No equivalent — absent key = zero value
Rust (serde)None (Option<T>)No equivalent — absent key = None

Python

import json

data = {"name": "Alice", "age": None}
print(json.dumps(data))
# → '{"name": "Alice", "age": null}'

parsed = json.loads('{"name": "Alice", "age": null}')
print(parsed["age"])        # None
print("missing" in parsed)  # False — use `in` to distinguish absent from null

Java + Jackson

// Jackson serialises Java null → JSON null
// Use @JsonInclude to control whether null fields are sent:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
    public String name;
    public Integer age;  // null → field omitted from JSON output
}

Common bugs caused by this distinction

Bug 1 — optional field never reaches the server

// ❌ Bug: clearing a field by setting it to undefined
const patch = { name: "Alice", nickname: undefined };
await fetch("/api/user/1", { method: "PATCH", body: JSON.stringify(patch) });
// Server receives: {"name":"Alice"} — nickname was never sent

// ✅ Fix: use null to explicitly signal "clear this field"
const patch = { name: "Alice", nickname: null };
// Server receives: {"name":"Alice","nickname":null} — field cleared

Bug 2 — short-circuit expression produces undefined

// ❌ Bug: if discount is null, discount.code is never reached,
//         the && returns null, which is fine — but what if discount
//         is an object without a .code property? Returns undefined.
const payload = {
  userId: 42,
  couponCode: discount && discount.code,  // could be undefined!
};
JSON.stringify(payload);
// → '{"userId":42}'  — couponCode silently dropped

// ✅ Fix: default to null
const payload = {
  userId: 42,
  couponCode: (discount && discount.code) ?? null,
};

Bug 3 — loose equality check conflates null and undefined

const data = JSON.parse('{"name":"Alice"}');

// ⚠️ Both null and undefined pass == null — you can't tell which
if (data.age == null) {
  console.log("age is null or undefined");  // true — but which?
}

// ✅ Be explicit
if (data.age === null) {
  console.log("age was sent as null");
} else if (!("age" in data)) {
  console.log("age was not included in the response");
}

null in JSON Schema

JSON Schema has a null type for nullable fields. There is no undefined keyword — optional fields are expressed by omitting them from required:

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age":  { "type": ["integer", "null"] }  // integer or explicitly null
  },
  "required": ["name"]
  // "age" is optional — if absent, key simply does not appear
}

Quick reference

ScenarioResult
JSON.stringify(undefined)undefined (JS primitive, not a string)
JSON.stringify({a: undefined})'{}' — key silently dropped
JSON.stringify([undefined])'[null]' — replaced to preserve index
JSON.stringify(null)'null' — valid JSON
JSON.parse('null')null (JS)
Access absent key after JSON.parseundefined — JS default, not from JSON
Convert undefinednullJSON.stringify(obj, (k, v) => v === undefined ? null : v)
Distinguish absent vs null in parsed object'key' in obj (not obj.key !== undefined)

Frequently Asked Questions

Does JSON support undefined?

No. The JSON specification defines exactly six value types: string, number, boolean (true/false), null, object, and array. undefined is a JavaScript concept — it does not exist in JSON and cannot be represented in a JSON document.

What happens when you JSON.stringify undefined?

It depends on location. At the top level, JSON.stringify(undefined) returns the JS primitive undefined (not a string). As an object property, the key is silently omitted. As an array element, it is replaced with null to preserve the array's length.

What is the difference between null and undefined in JSON?

null is a valid JSON value — it explicitly represents "no value." undefined does not exist in JSON. When a JavaScript object has a property set to undefined and is serialised with JSON.stringify, that property is dropped entirely from the output string.

How do I keep undefined values in JSON output?

Use a replacer function: JSON.stringify(obj, (key, val) => val === undefined ? null : val). This converts all undefined values to null, keeping every key in the output.

What does null mean in JSON Schema?

JSON Schema has a null type for nullable fields: type: ["string", "null"]. There is no undefined keyword — optional fields are expressed by omitting them from the required array.

Format and validate your JSON in the browser

Paste any JSON payload to pretty-print it, spot null fields, or validate the structure — no data is sent to a server.

JSON Formatter JSON Validator Schema Generator

Need to inspect a payload with null values right now? Pretty-print it in the browser.

Open JSON Formatter →
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds developer tools at JSON Dev Tools.