Unexpected character encountered while parsing value: <

ErrorC#

Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.

Where JSON.parse stops

<!DOCTYPE html>
<html><body>502 Bad Gateway</body></html>

What it means

Newtonsoft.Json read a character that cannot start a JSON value, and the message names it after the colon. A < means an HTML page arrived where JSON was expected. line 0, position 0 means it failed on the first character, so nothing in your class is the cause.

Last verified on System.Text.Json 10.0; Newtonsoft.Json 13.0.

The validator opens with the error marked. Examples travel in the URL fragment, which browsers never send to a server.

Express Lint lays broken JSON out by bracket depth and marks the line where it stops. It changes only spaces and line breaks outside strings. Strings in either quote stay as written. If the quotes do not pair up, it leaves your text as it is. Ctrl+Z undoes it. See how it works.

Usually
<: the body is an HTML pagee or u: plain text, or undefinedReading Path, line and positionAfter parsing a value an unexpected character was encountered: a comma is missingUnterminated string. Expected delimiter: the text stops earlyNewtonsoft accepts what System.Text.Json rejects
Fix
Log the raw body and the status code before you deserialize.

The fix

Log the raw body and the status code before you deserialize. If the body is an HTML page, fix the request or the proxy, not the class. The two samples here are the same failed call: what arrived, and what the API should have sent.

broken.jsonFails to parse
<!DOCTYPE html>
<html><body>502 Bad Gateway</body></html>
JSON.parse stops at line 1, column 1.

Lines 1, 2, 3 and 4 change.

fixed.jsonParses
{
  "error": "bad gateway",
  "status": 502
}
JSON.parse reads it.

How the message appears

The first line is the example on this page. Then the same message for plain text and for the word undefined, a missing comma, and a string that stops early. A comma after the last member, single quotes and an empty body throw nothing in Newtonsoft, so they have no line here.

Console
  • Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
  • Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: e. Path '', line 0, position 0.
  • Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: u. Path 'status', line 1, position 21.
  • Newtonsoft.Json.JsonReaderException: After parsing a value an unexpected character was encountered: ". Path 'id', line 3, position 2.
  • Newtonsoft.Json.JsonReaderException: Unterminated string. Expected delimiter: ". Path 'status', line 1, position 25.

What causes it

  1. <: the body is an HTML page

    A 502 from a proxy, a 404 page, a login redirect or a WAF challenge usually comes back as HTML. Your code asked for JSON and read the page. Path '' is the top of the document, and line 0, position 0 is what Newtonsoft says when it fails on the first character. Log the body and the status code.

  2. e or u: plain text, or undefined

    A text error such as error: upstream timeout gives while parsing value: e. The word undefined gives while parsing value: u, with Path 'status' naming the field that held it. A client that builds JSON by joining strings writes undefined when a variable has no value. See undefined is not valid JSON for the JavaScript side.

  3. Reading Path, line and position

    Path is the property being read. Path '' is the top, and Path 'status' is the status property. Past the first character the line count starts at 1. In the undefined example the u is the 21st character on line 1, and the message says position 21. In the missing comma example the quote is the third character on its line, and the message says position 2. So the position is close, not exact. Read the Path and the character it names as well.

  4. After parsing a value an unexpected character was encountered: a comma is missing

    The example has no comma after "id": 7. Newtonsoft read the 7, then met the quote of "status" on the next line. Path 'id' is the last property it read, and line 3 is the line of the quote. Add the comma at the end of the line above.

  5. Unterminated string. Expected delimiter: the text stops early

    A string with no closing quote at the end of the text gives Unterminated string. Expected delimiter. The Path names the property that was open, Path 'status' here. Look for a connection that dropped or a buffer that was cut.

  6. Newtonsoft accepts what System.Text.Json rejects

    A comma after the last member and single quotes both read with no error. So does an empty body: DeserializeObject<Order> throws nothing, so there is no error at the read and the problem shows up later, where your code uses the result. System.Text.Json rejects all three, so a payload that worked here can fail after you switch. See the System.Text.Json page.

Worth knowing

NoteThe same failure in other languages: JavaScript says Unexpected token '<', "<!DOCTYPE "... is not valid JSON (the JavaScript page), and Jackson says Unexpected character ('<' (code 60)) (the Jackson page).

NoteThe messages here come from JsonConvert.DeserializeObject<Order> into a small class with an Id and a Status. Other entry points, such as JObject.Parse, were not run.

Your JSON and text are processed entirely in your browser and are never sent anywhere. To understand how the site is used we record each page view (the page, the referrer and an approximate location from your IP address) and keep it for 90 days. Nothing is stored on your device unless you choose it. Accept to also store a device identifier here and record your browser and device characteristics, which is what lets a return visit be told from a new one. Decline and nothing is sent at all. We respect Do Not Track. See our privacy policy.