The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →If a browser request to a mocked Fastify GET route fails with “No ‘Access-Control-Allow-Origin’ header,” register @fastify/cors on the Fastify instance before calling listen(). Different localhost ports are different origins, so a frontend at http://localhost:5050 and an API at http://localhost:3000 need a CORS response that permits the frontend origin.
Why a GET route on another localhost port is blocked
An origin consists of the scheme, host, and port. Although both URLs use localhost, http://localhost:5050 and http://localhost:3000 are different origins. Browsers enforce Cross-Origin Resource Sharing (CORS) when page code requests a resource from a different origin.
A March 2025 Linux Foundation LFW111 forum post describes this exact setup: a frontend at http://localhost:5050 fetching http://localhost:3000/confectionery, with the browser reporting that no Access-Control-Allow-Origin header was present. The poster reported that adding origin: "*" to their Fastify CORS registration resolved the issue; this is an individual reproduction report, not a controlled test. Read the forum report.
Register CORS on the Fastify server
The @fastify/cors plugin adds a request hook and a wildcard OPTIONS route. Register it on the same Fastify instance as the route, before the server starts accepting requests. The following example allows a frontend from http://localhost:5050 to call a mock route on port 3000:
#1 Best Overall
import Fastify from 'fastify'
import cors from '@fastify/cors'
const fastify = Fastify()
await fastify.register(cors, {
origin: 'http://localhost:5050',
methods: ['GET', 'HEAD', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization']
})
fastify.get('/confectionery', async () => ({
items: []
}))
await fastify.listen({ port: 3000 })
The plugin’s documented default origin is *, and its default methods are GET, HEAD, and POST. Setting the origin explicitly makes the allowed frontend clear; listing OPTIONS in this example also makes the intended preflight method apparent. See the official @fastify/cors README for the plugin’s options and version-specific details.
Choose an origin policy that matches the request
| Configuration | When it fits | Important constraint |
|---|---|---|
origin: '*' |
A deliberately open, non-credentialed local mock. | Browsers do not allow this wildcard for credentialed requests. |
origin: 'http://localhost:5050' |
A frontend with a known origin; use the actual scheme, host, and port. | The response must permit the origin making the request. |
Explicit origin plus credentials: true |
A request flow that intentionally uses browser credentials such as cookies. | Return the explicit allowed origin, not *; the response must also allow credentials. |
The Access-Control-Allow-Origin response header tells the browser whether requesting code from an origin may read the response. It can contain one permitted origin or * for requests without credentials; with credentials, the wildcard is blocked. See MDN’s header reference.
For a cookie-based request, configure the plugin deliberately, for example with origin: 'http://localhost:5050' and credentials: true, and have the browser request include credentials where needed. The response must include Access-Control-Allow-Credentials: true as well as the explicit allowed origin. Do not combine credentialed browser requests with origin: '*'. A simple GET is not normally preflighted, but its response still needs the credential permission before browser code can read it. MDN’s CORS guide explains the browser behavior.
Know when a GET triggers an OPTIONS preflight
A simple cross-origin GET normally goes straight to the GET request. A browser may send an OPTIONS preflight first when the request uses non-simple conditions, such as certain custom headers or a non-simple method. The preflight asks whether the intended method and headers are allowed.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
- The browser sends
OPTIONSwith headers such asAccess-Control-Request-Methodand, when applicable,Access-Control-Request-Headers. - The server responds with CORS permission headers.
Access-Control-Allow-Methodsmust cover the requested method, andAccess-Control-Allow-Headersmust cover the requested headers. - If the preflight succeeds, the browser sends the intended request. If it fails, the browser blocks that request from page code.
For example, a GET carrying an Authorization header may need that header included in the plugin’s allowedHeaders configuration. A POST or another method also needs to be included in the permitted methods. The plugin documents controls including methods, allowedHeaders, preflight, strictPreflight, and optionsSuccessStatus; use the official plugin documentation for their exact behavior.
MDN describes the preflight exchange and the role of the allow-method and allow-header response headers in its CORS guide.
Rank #4
Debug the missing-header error
- Write down both origins. Include scheme, host, and port for the page and API; a port difference is enough to make them cross-origin.
- Inspect the actual response in browser DevTools. For the GET, check whether
Access-Control-Allow-Originis present and whether its value permits the page origin. - Look for an OPTIONS request. If one appears before the GET, inspect its
Access-Control-Request-MethodandAccess-Control-Request-Headers. - Compare requested and allowed values. Ensure the configured methods and headers cover what the preflight requests.
- Check plugin registration. Confirm
@fastify/corsis registered on the same Fastify instance and beforelisten(). - Check credentials as a pair. If the browser sends credentials, confirm the response uses the explicit frontend origin and
Access-Control-Allow-Credentials: true; a wildcard origin will not work. - Separate routing from browser policy. Use curl or Postman to check whether the route responds, but remember that these clients do not enforce the browser’s CORS checks.
Global plugin configuration or a route override?
Registering the plugin globally is usually the clearest approach when multiple routes should share one CORS policy. The plugin also supports route-level configuration; use an override only when a route genuinely needs a different policy, and verify the resulting response headers for that route. In either case, CORS controls whether browser code may read a cross-origin response—it does not make an unavailable route exist or replace application authentication.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




