How to Fix SyntaxError: Unexpected token < in JSON at position 0

The SyntaxError: Unexpected token < in JSON at position 0 error indicates that JavaScript code received non-JSON data, usually HTML, instead of the expected JSON. To fix the issue, examine the received data to determine the problem. If using fetch() or JSON.parse(), log the data to the console and check for common issues such as incorrect URLs, server errors, or variable assignment and character encoding problems.


This guide will help to fix SyntaxError: Unexpected token < in JSON at position 0. This guide also applies to these other common variants of the same error:

Summary

These errors indicate your JavaScript code expected to receive JSON but got something else instead (probably HTML in the form of a server-side error). To fix the issue you need to examine what you got instead of the expected JSON to determine what the problem is.

Details

Usually this error is caused when your server returns HTML (which typically begins with <DOCTYPE html> or <html>) instead of JSON. Valid JSON cannot begin with a < character, so the JSON parser knows immediately the data isn't valid JSON and produces one of the error messages mentioned above.

To fix this error you need to figure out why you're getting HTML (or something else) instead of the JSON you expected. To do this you need to log the data you're trying to parse to the console.

If you're using fetch()

Use this approach if your code looks something like this:

fetch('https://example.com/some/path/to/json')
.then(function (response) {
    return response.json();
})
.then(function (data) {
    // Do something with data
});

In this case the error is thrown when response.json() tries to run and fails to parse the data from the server as JSON. You can add a function to handle the error and display the raw text of the response body from the server and log it to the console (see notes about commented lines below):

var responseClone; // 1
fetch('https://example.com/some/path/to/json')
.then(function (response) {
    responseClone = response.clone(); // 2
    return response.json();
})
.then(function (data) {
    // Do something with data
}, function (rejectionReason) { // 3
    console.log('Error parsing JSON from response:', rejectionReason, responseClone); // 4
    responseClone.text() // 5
    .then(function (bodyText) {
        console.log('Received the following instead of valid JSON:', bodyText); // 6
    });
});

Here's an explanation of each line with a numbered comment:

  1. A responseClone variable is required to hold a clone of the response object because the body of a response can only be read once. When response.json() is called the body of the original response is read, which means it cannot be read again when handling the JSON parse error. Cloning the response to responseClone provides two copies of the response body to work with; one in the original response to use with response.json() and another to use with responseClone.text() if response.json() fails.
  2. This line populates the responseClone variable with a clone of the response received from the server.
  3. A second function argument is passed to the then() function that follows the response.json() call. This second function will be called if the promise from response.json() is rejected (i.e. a JSON error is encountered).
  4. This line logs the rejectionReason from the rejected response.json() promise and the responseClone so it can be examined if needed (the HTTP status code is often useful for debugging, for example).
  5. Instead of trying to parse the response body from the server as JSON it is processed as raw text.
  6. The body text is logged to the console for examination.

If you're using JSON.parse()

Use this method if the code that's throwing the error looks like this:

JSON.parse(data);

In this case you can log the data to the console if an error is encountered to see what it contains:

try {
    JSON.parse(data);
}
catch (error) {
    console.log('Error parsing JSON:', error, data);
}

What do I do next?

Once you can see the data that's causing the JSON parse error it will hopefully provide a clue as to why you're not getting the valid JSON you expect. Some of the most common issues that lead to this error are: