Sentry Answers>JavaScript>

How do I fix the "TypeError: Failed to fetch" error in JavaScript?

How do I fix the "TypeError: Failed to fetch" error in JavaScript?

Richard C.

The ProblemJump To Solution

The JavaScript fetch command is available in browsers and Node.js and enables a program to make an HTTP request. Even though you made an apparently valid request to a valid URL, you might still get an error like TypeError: Failed to fetch.

The Solution

First check the possible network causes if you haven’t already:

  • Is your app behind a firewall or proxy that’s preventing it from reaching the target URL? Can you connect to the URL from another computer’s browser or by using curl?
  • Is the URL correctly spelled, including https or http and a trailing / or not?
  • If you are using Docker, is the container listening on all ports? If you are trying to call from the container to your localhost, are you using http://host.docker.internal as the URL and have you configured your network to see it?

If the problem does not have a network solution, the most likely cause is a CORS (cross-origin resource sharing) error. Browsers and servers are wary of letting programs on one domain, subdomain, or port call those on another, as this is a security risk. For example, if you as a user browse a website, you don’t want any JavaScript that the site loads into your browser to be able to make calls to your bank account where you are logged in.

Web servers have CORS policies that specify what extra domains may make requests to the server. This is true whether you use a server you wrote, like in Node.js or Go, or a traditional server like Apache or Nginx. You need to configure CORS in any server that is called from a domain other than the one it hosts.

For example, if you run an Express.js server that returns Hello World! in a GET method at http://localhost:3000 like this:

Click to Copy
import express, { Request, Response } from 'express'; const app = express(); app.get('/', (req: Request, res: Response) => { res.send('Hello World!'); }); app.listen(port);

You’ll get an error if you call this URL in a fetch command from a browser page on http://localhost:3001 because it’s using a different port from the server:

Click to Copy
GET http://localhost:3000/ net::ERR_FAILED 200 (OK) Access to fetch at 'http://localhost:3000/' from origin 'http://localhost:3001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Note that the request succeeded with a response code of 200. However, the browser denies access to the content of the response since no CORS header was returned by the server.

Generally, you need to set only two CORS headers on your server to get fetch requests to work:

  • Access-Control-Allow-Credentials: set this to true if you use any cookies for authentication in your app that need to be passed to the server.
  • Access-Control-Allow-Origin: set this to a list of domains that you wish to allow access to your server.

We can modify the example Express.js example above to have it return a usable response now:

Click to Copy
import express, { Request, Response } from 'express'; const app = express(); app.get('/', (req: Request, res: Response) => { res.setHeader('Access-Control-Allow-Credentials', 'true'); if (req.headers.origin && ['http://localhost:3000', 'http://localhost:3001'].includes(req.headers.origin)) { res.setHeader('Access-Control-Allow-Origin', req.headers.origin); } res.send('Hello World!'); }); app.listen(3000);

If you are using a server that you wrote in Go or Python you can set these headers programmatically in a similar way to the example above. Consult your web framework’s documentation on how to do this.

For traditional standalone servers with configuration files, setting headers can be poorly documented. We recommend asking AI for examples to get started, and reading this website, which has a list of servers and their configuration CORS settings.

Using a Third-party Server

You might have a web application in the browser that gets a CORS error when calling a server that you did not write, like a public API. Unless you can get the API developer to change their server’s CORS policy, there is nothing you can do to fix the problem.

However, it might be that their server is not meant to be called from the browser and is intended only for server-to-server communication. In that case, you need to write a method on your server that communicates with their server and get your browser application to call your server’s method instead of theirs. In this way, your server acts as a proxy between your user’s browser and the public server it wants to contact. This will avoid the CORS error because your server can ignore it, unlike a web browser.

Warning: Use Anti-CSRF Tokens

Be careful when enabling CORS on your server that you do not inadvertently allow attackers to make fraudulent calls to your users’ accounts on their behalf. To be sure your application is protected, add anti-CSRF tokens (cross-site request forgery) to all forms in your application. If the token submitted by a request does not match the one you generated for the user on the page, then the request must be rejected.

Further Reading

Please read this MDN article on CORS for more detailed information.

  • ResourcesImprove Web Browser Performance - Find the JavaScript code causing slowdowns
  • ResourcesJavaScript Frontend Error Monitoring 101
  • Syntax.fm logo
    Listen to the Syntax Podcast

    Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.

    SEE EPISODES

Loved by over 4 million developers and more than 90,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.

© 2024 • Sentry is a registered Trademark
of Functional Software, Inc.