SyntaxError: Unexpected token < in JSON at position 0

The most common reason for this error is attempting JSON to parse an HTML or XML response. The HTML and XML documents start with <, and JSON identifies it as an unparsable string. It is also possible that you are requesting an api that you don’t have permission to access. In that case, you expect a JSON, but the server returns a permission denial HTML.

This article demonstrates several JSON parsing errors with code examples.

Reason for Unexpected token < in JSON error

Listed below is a simple express.js route that generates an HTML response. It can be any api endpoint. The api generates the HTML response <p>This is an HTML response</p>.

router.post("/user/create/html", (request, response) => {
    const reply = "<p>This is an HTML response</p>"
    response.set('Content-Type', 'text/html');
    response.send(reply);
});

Now let’s find out what happens when we try to parse this response with the JSON parser. The code makes a post request to the endpoint that produces an HTML response. Then it tries to JSON parse the response.

const serverHtmlResponse = await axios.post('/user/create/html')
console.log(serverHtmlResponse.headers["content-type"])
console.log(serverHtmlResponse.data)
console.log(typeof serverHtmlResponse.data)
const htmlResponse = JSON.parse(serverHtmlResponse.data)

Unexpected token < in JSON errorFigure 1 : Unexpected token < in JSON error

Note that the endpoint’s response type is text/html and the content is <p>This is an HTML response</p>. The content is not parsable. Thats the reason you see the first character of the content < in the error message.

Reason for Unexpected token o in JSON at position 1

That error happens when we attempt to JSON parse an object.
The below express.js route produces a JSON object as the response.

router.post("/user/create/json", (request, response) => {
   const reply = "This is a JSON object response"
   response.json({response:reply});
});

The response of this endpoint is {response: ‘This is a JSON object response’}. That is not a JSON string. It is an object. The console.log(typeof serverJsonResponse.data) proves the api response is an object.

const serverJsonResponse = await axios.post('/user/create/json')
console.log(serverJsonResponse.headers["content-type"])
console.log(typeof serverJsonResponse.data)
console.log(serverJsonResponse.data)
const jsonResponse = JSON.parse(serverJsonResponse.data)

 Unexpected token o in JSON at position 1Figure 2 : Unexpected token o in JSON at position 1

Therefore, what happens here is JSON.parse(“[object Object]”)
and JSON complains about the character “o” it encountered first.

How to parse a JSON string correctly?

The JSON.parse() method accepts a string that correctly represents a JSON object. In other words, a string that is parsable into a JSON object.
Below is an express route that produces a JSON string like {“response”:”This is a JSON string response”}.

router.post("/user/create/jsonstring", (request, response) => {
   const reply = `{"response":"This is a JSON string response"}`
   response.json(reply)
});

The response is application/json, and the type is string. This type of response is parsable with JSON parser as long as the response string can represent a valid object.

const serverResponse = await axios.post('/user/create/jsonstring')
console.log(serverResponse.headers["content-type"])
console.log(typeof serverResponse.data)
console.log(serverResponse.data)
const jsonStringResponse = JSON.parse(serverResponse.data)