Why Am I Getting SyntaxError Unexpected Token in JSON at Position 0
Problem
When I called my API from my Angular app, I got this error:
SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoadThe app worked fine in my browser during development. But when I deployed it to my Android device, this error appeared.
Environment
- Angular frontend app
- Spring Boot backend API
- Works in browser, fails on mobile device
What Happened?
I had a simple HTTP request that fetched user data:
this.httpclient.get('http://localhost:8080/users') .subscribe(data => { data = JSON.parse(JSON.stringify(data)); this.surgeonList = data.map(user => ({ name: user.lastname, icon: 'person' })); });In my browser dev tools, the response looked correct—valid JSON data. But on the Android device, the same request returned my entire index.html page instead of JSON.
I checked the raw response and saw:
<!DOCTYPE html><html><head> <title>My App</title>...That < at position 0 is the opening bracket of <html> or <!DOCTYPE>. The JSON parser sees this and immediately fails because < is not valid JSON syntax.
How to Debug This?
The error is not about JSON.parse being wrong. It’s about what your server actually returned.
I added logging to see the raw response:
this.httpclient.get('http://api.example.com/users', { responseType: 'text' }) .subscribe({ next: (text) => { console.log('Raw response:', text.substring(0, 100)); console.log('First char:', text.charAt(0));
if (text.startsWith('<') || text.startsWith('<!')) { console.error('Server returned HTML, not JSON!'); // Check: wrong endpoint? authentication redirect? server error? } }, error: (err) => console.error('Request failed:', err) });When I ran this on the device, I confirmed: the response started with <!DOCTYPE.
Why Did My Server Return HTML?
I found three common causes:
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐│ Wrong URL │ │ Auth Redirect │ │ Server Error ││ (404 → error │ │ (302 → login │ │ (500 → error ││ page) │ │ page) │ │ page) │└──────────────────┘ └──────────────────┘ └──────────────────┘In my case, the mobile app was calling localhost:8080 which doesn’t exist on the device. The backend server was on a different machine. When the request failed, the server’s fallback routing returned index.html.
How to Solve It?
Step 1: Check your API URL
Make sure your device can reach your server. Use the actual server IP or domain, not localhost.
// Wrong for mobile:this.httpclient.get('http://localhost:8080/users')
// Correct:this.httpclient.get('http://192.168.1.100:8080/users')// orthis.httpclient.get('https://api.myapp.com/users')Step 2: Verify Content-Type header
Check what your server claims to return:
fetch('/api/users') .then(response => { const contentType = response.headers.get('content-type'); console.log('Content-Type:', contentType);
if (!contentType || !contentType.includes('application/json')) { console.error('Server did not return JSON!'); throw new Error('Expected JSON, got ' + contentType); } return response.json(); });Step 3: Handle errors properly
Don’t blindly parse everything as JSON:
this.httpclient.get<User[]>('/api/users') .subscribe({ next: (users) => { // Angular HttpClient already parses JSON // No need for JSON.parse(JSON.stringify()) this.userList = users.map(u => ({ name: u.lastname })); }, error: (err) => { console.error('HTTP error:', err.status, err.message); // Check err.error for actual response body if (err.error?.text?.startsWith('<')) { console.error('Server returned HTML page instead of JSON'); } } });A Note on Angular HttpClient
Angular’s HttpClient automatically parses JSON responses. You don’t need to call JSON.parse yourself:
// DON'T do this:data = JSON.parse(JSON.stringify(data));
// DO this: Angular already parsed itthis.httpclient.get<User[]>('/api/users') .subscribe(users => { // users is already a proper User[] array });The double parse in my original code was unnecessary and made debugging harder.
Summary
In this post, I explained why “Unexpected token < in JSON” occurs. The key point is: your server returned HTML instead of JSON. Debug by checking the actual response content, not just the error message. Common causes include wrong API URLs, authentication redirects, and server error pages.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments