CORS issue with Spring Boot
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A CORS problem in Spring Boot usually means the browser sent a cross-origin request and the server did not answer with the headers needed to allow it. The tricky part is that the actual fix depends on where the request is being blocked: controller mapping, global MVC configuration, preflight handling, or Spring Security.
What the Browser Is Expecting
Browsers enforce the same-origin policy. If a frontend from one origin calls an API at another origin, the server must respond with headers such as Access-Control-Allow-Origin.
For non-simple requests, the browser first sends an OPTIONS preflight request. If that preflight fails, your actual GET, POST, or PUT request never leaves the browser.
That is why a backend can appear to work fine in Postman but still fail from the browser.
Controller-Level Configuration
For a small application or a single endpoint, @CrossOrigin is often enough:
This is convenient when only a few controllers should be callable from the frontend.
Global MVC Configuration
If many endpoints need the same CORS policy, configure it globally:
This is cleaner when the policy is shared across your API.
Spring Security Changes the Picture
A very common mistake is adding MVC CORS config but forgetting that Spring Security also has to allow the request. If Security handles the request first and rejects the preflight, your MVC CORS config never helps.
A modern SecurityFilterChain setup should explicitly enable CORS:
Without .cors(...), developers often see confusing preflight failures and assume the MVC configuration is broken.
Credentials and Wildcards
Another frequent trap is mixing credentials with a wildcard origin. If the browser sends cookies or authorization headers, you cannot use * together with allowCredentials(true) in the way many people first try.
Instead, specify the exact allowed origin or a controlled pattern.
That matters especially for session-based applications where the frontend and backend run on different local ports during development.
How to Debug It
When debugging a CORS problem, check these in the browser network tab:
- the preflight
OPTIONSrequest - the response status code
- '
Access-Control-Allow-Origin' - '
Access-Control-Allow-Methods' - '
Access-Control-Allow-Headers' - whether credentials are being sent
Also compare the frontend origin exactly, including scheme and port. http://localhost:3000 and http://localhost:5173 are different origins.
Common Pitfalls
- Configuring CORS in controllers but forgetting to enable it in Spring Security is one of the most common failures.
- Using
*while also expecting cookies or authenticated cross-origin requests usually does not behave the way developers want. - Ignoring the browser preflight request makes debugging much harder because the real request may never be sent.
- Testing only with Postman can hide the issue because CORS is a browser security rule, not a generic HTTP rule.
- Allowing every origin in production is easy but often a bad security choice when the API is supposed to be used only by known frontends.
Summary
- A Spring Boot CORS issue is usually about missing or mismatched response headers for a browser cross-origin request.
- '
@CrossOriginworks well for small, local cases.' - Global MVC configuration is better when the policy applies across many endpoints.
- If Spring Security is present, enable CORS there too or preflight requests may still fail.
- Always debug with the browser network panel, because Postman does not reproduce browser CORS enforcement.

