JSON Errors / Rust

serde_json: expected value / missing field errors

How to Fix: serde_json: expected value / missing field errors

serde_json reports three distinct failure families, and the wording tells you which you have: "expected value at line 1 column 1" means the input is not JSON at all (empty, HTML, or truncated); "missing field 'name'" means valid JSON that lacks a field your struct requires; "invalid type: string, expected u64" means a field exists but with the wrong type.

Every error carries line and column positions, and serde_json is strict by design - the fix is almost always in your struct definition, not a parser setting.

{"find": "error"}paste your JSON below

Common causes

1. "expected value at line 1 column 1" - non-JSON input

The Rust equivalent of the JavaScript position-0 errors: an empty body, an HTML error page, or a truncated response reached from_str.

2. "missing field" - struct requires what the JSON omits

Non-Option fields are mandatory. An API that omits null fields entirely will break structs that declare them as required.

Invalid
#[derive(Deserialize)]
struct User { name: String, nickname: String }
// JSON: {"name": "Ada"} -> Error: missing field `nickname`
Valid
struct User { name: String, nickname: Option<String> }

3. "invalid type" - number/string mismatches

APIs that send numbers as strings ("42") or booleans as 0/1 clash with strongly typed fields.

How to fix it

Make optional fields Option or defaulted
#[derive(Debug, Deserialize)]
struct User {
    name: String,
    nickname: Option<String>,      // absent or null -> None
    #[serde(default)]
    tags: Vec<String>,             // absent -> empty vec
}
Map snake_case/camelCase and renamed keys
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct Order {
    order_id: u64,                 // matches JSON "orderId"
    #[serde(rename = "totalUSD")]
    total_usd: f64,
}
See what actually failed
match serde_json::from_str::<User>(&body) {
    Ok(user) => println!("{user:?}"),
    Err(e) => {
        eprintln!("parse failed at line {} col {}: {e}", e.line(), e.column());
        eprintln!("body head: {:.200}", body);
    }
}

Frequently asked questions

How do I accept a number that sometimes arrives as a string?

Use a custom deserializer or an untagged enum: #[serde(untagged)] enum NumOrStr { N(u64), S(String) }, then normalize after parsing. Crates like serde_with also provide DisplayFromStr for exactly this pattern.

Does serde_json ignore unknown fields?

Yes by default - extra JSON fields are silently skipped. To make them errors (strict schema validation), add #[serde(deny_unknown_fields)] to the struct.

What about parsing without defining structs?

Parse into serde_json::Value for exploratory work: let v: Value = serde_json::from_str(&body)?. You lose type safety but nothing can be "missing" - useful for debugging exactly which shape arrived before writing the struct.

Last updated:

Related JSON errors

You might also need

Free and in-browser, like everything on JSON Console. Browse all tools →