Parsing and encoding errors: unexpected token, malformed input
"Unexpected token", "unexpected end of input", "invalid UTF-8", "malformed" — a parser rejected its input. The parser is almost never wrong; the interesting question is why the input isn't what you think it is, and the answer is usually one layer earlier than the error.
Read the message like a parser
| "Unexpected token < in JSON at position 0" | The input starts with < — it's HTML, not JSON. An error page, a login redirect, or a 404 came back where the API response should be. Log the raw body and the status code. |
| "Unexpected end of JSON input" | Truncated: an empty response body, a connection cut mid-transfer, or a partially written file. Valid JSON doesn't stop early. |
| "Unexpected token" mid-document | Genuinely malformed at that spot: trailing commas, single quotes, unescaped newline in a string, NaN/undefined serialized by hand-built formatting, or two JSON objects concatenated. |
| "Invalid UTF-8" / mojibake (é, ’) | Bytes in one encoding decoded as another — a Latin-1 database column read as UTF-8, a file saved in the wrong encoding, or binary data pushed through a text path. |
Look at the actual bytes
curl -s https://api.example.com/data | head -c 200 # what actually comes back? head -c 64 payload.json | xxd # BOM? binary? wrong file?
Most parse errors dissolve the moment you look at the raw input instead of the parsed
result: the "JSON" that is an HTML error page, the file with a UTF-8 BOM
(EF BB BF) that a strict parser rejects, the config saved as UTF-16 by a
Windows editor. If the error names a position, count to it — the byte offset points at the
exact problem in a way re-reading the code never will.
The layer-before rule
Treat a parse error as a symptom and find the producer: the API that returns HTML on error
(fix: check content-type and status before parsing), the shell pipeline that
mixed stderr into stdout, the template that string-concatenates JSON instead of using a
serializer, the double-encoded payload (JSON.stringify applied twice — the
tell is a quoted string full of \"). Hand-built serialization is the root
cause behind a remarkable share of these; use the library serializer, always name the file
and offset in your own error messages, and validate at the boundary so bad input fails
where it enters, not three modules later.
Documented occurrences
153 analyzed errors across 42 libraries match this failure class. Each links to the thrown message, its source line, and documented fixes.
gohugoio/hugo
- failed to parse file %q: %s
- failed to parse root certificate
- failed to parse certificate PEM
- failed to parse certificate: %v
- failed to decode languages config: %w
- +24 more in hugo
docker/cli
- failed to parse hook template
- failed to parse hook template: flagValue: cmd is nil
- failed to parse hook template: flagValue: no flags found
- failed to parse hook template: arg: cmd is nil
- failed to parse hook template: arg: %dth argument not set
- +8 more in cli
vercel/next.js
- Invalid JSON
- Failed to parse source map URL for ${filename}.
- Failed to parse source map for ${filename}.
- Failed to parse source map ${sourceMapFilename}.
- failed to decode param
- +3 more in next.js
aio-libs/aiohttp
- WSCloseCode.INVALID_TEXT: Invalid UTF-8 text message
- WSCloseCode.INVALID_TEXT: Invalid UTF-8 text message
- Malformed Digest auth challenge: Missing 'realm' parameter
- Malformed Digest auth challenge: Missing 'nonce' parameter
- Reader did not read all the data or it is malformed
- +3 more in aiohttp
rails/rails
- Malformed command: #{data.inspect}
- Malformed Mailgun raw email
- Malformed Mailgun recipient
- Malformed Mandrill events payload
- Malformed Postmark raw email
- +3 more in rails
rust-lang/cargo
- failed to parse process output: {}
- invalid character `+` in dependency name: `+{toolchain}` Use `cargo +{toolchain} add` if you meant to use the `{toolchain}` toolchain.
- invalid character `+` in package name: `+{toolchain}` Use `cargo +{toolchain} install` if you meant to use the `{toolchain}` toolchain.
- invalid character `+` in package name: `+{toolchain}` Use `cargo +{toolchain} update` if you meant to use the `{toolchain}` toolchain.
- malformed output when learning about crate-type {} information {}
- +2 more in cargo
gofiber/fiber
- failed to parse client CA certificate from %q
- failed to decode session data: %w
- failed to decode session data: %w
- failed to parse: %w
- fiber: failed to decode shared state %s value: %w
- +1 more in fiber
pypa/pip
- Failed to parse TOML in {scriptfile!r}
- [dependency-groups] table was malformed in {path}. Cannot resolve '--group' option.
- Sorry, {url!r} is a malformed VCS url. The format is <vcs>+<protocol>://<url>, e.g. svn+http://myrepo/svn/MyApp#egg=MyApp
- malformed extra: %s
- unable to parse identification
- +1 more in pip
apache/kafka
- Malformed consumer protocol subscription
- Malformed consumer protocol assignment
- ${about}: failed to parse hexadecimal number: ${cause}
- ${about}: failed to parse number: ${cause}
mongodb/node-mongodb-native
- Malformed JSON body in GET request.
- Malformed response body - missing field `access_token`.
- Malformed response body - missing field `expires_in`.
- Malformed response body - unable to parse int from `expires_in` field.
…and 32 more libraries — search for your exact message.