JSON Errors / Go

invalid character '<' looking for beginning of value

How to Fix: invalid character '<' looking for beginning of value

encoding/json found a character that cannot start (or continue) a JSON value. The quoted character is the diagnosis: '<' means an HTML page came back instead of JSON, "'" means single quotes were used, and '}' or ',' usually means a trailing comma or empty field.

The companion error "unexpected end of JSON input" is the truncation variant - the input stopped mid-document rather than containing a wrong character.

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

Common causes

1. invalid character '<' - HTML instead of JSON

The HTTP call returned an error page, redirect, or proxy response. Go will not stop you from unmarshaling a 500 response body - you must check the status code yourself.

2. invalid character '\'' - single quotes

JSON requires double quotes for all strings and keys.

Invalid
{'name': 'Ada'}
Valid
{"name": "Ada"}

3. invalid character '}' after object key:value pair - trailing comma

A comma after the last member makes the parser expect another pair, and it finds } instead.

Invalid
{"a": 1,}
Valid
{"a": 1}

How to fix it

Always check status and capture the body (Go)
resp, err := http.Get(url)
if err != nil {
    return err
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
    return err
}
if resp.StatusCode != http.StatusOK {
    return fmt.Errorf("HTTP %d: %s", resp.StatusCode, body)
}
if err := json.Unmarshal(body, &result); err != nil {
    return fmt.Errorf("decode failed: %w; body: %.200s", err, body)
}
Get the exact byte offset of the error
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
    fmt.Printf("syntax error at byte offset %d\n", syntaxErr.Offset)
    fmt.Printf("context: %.40s\n", body[max(0, syntaxErr.Offset-20):])
}

Frequently asked questions

Why does Go not include line numbers in JSON errors?

json.SyntaxError carries a byte Offset instead - JSON payloads are often single-line, where line numbers are useless. Convert the offset to line/column by counting newlines in the input before that offset, or slice the surrounding bytes for context as in the example.

What does "cannot unmarshal string into Go struct field" mean?

A different error class: the JSON is syntactically valid but a field's type does not match your struct - e.g. "42" (string) arriving into an int field. Fix the struct type, or use json.Number / a custom UnmarshalJSON for APIs that send numbers as strings.

Is there a stricter decoder that catches unknown fields?

Yes: dec := json.NewDecoder(r); dec.DisallowUnknownFields() makes decoding fail when the payload has fields your struct lacks - useful for catching schema drift early instead of silently ignoring new data.

Last updated:

Related JSON errors

You might also need

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