CORS Preflight Request Blocked by Railway Edge Proxy

yuriney
FREEOP

5 months ago

I’m currently experiencing an issue with CORS when deploying my Spring Boot backend on Railway.

My frontend is hosted at:
https://allcleanlaundry.onrender.com

My backend is hosted at:
https://allcleanlaundry-production.up.railway.app

When my frontend makes a request to the backend, the browser sends a CORS preflight OPTIONS request with the Origin header set to my frontend URL. However, I consistently receive a 403 Forbidden response with the message:

I have verified that:

My Spring Boot backend is properly configured to allow CORS from https://allcleanlaundry.onrender.com and responds to OPTIONS requests.
CORS works correctly when I test the same setup locally.
The OPTIONS request directly to the Railway-hosted backend also returns 403 Forbidden.

It seems that the Railway edge proxy is blocking or rejecting these preflight CORS requests.

Can you confirm if there are any restrictions or special configurations required to allow CORS preflight (OPTIONS) requests through Railway’s edge proxy?

$10 Bounty

13 Replies

Anonymous
PRO

5 months ago

What are the request options you are sending? Maybe it has to do something with that.


smolpaw
HOBBY

5 months ago

Let me see the code where you configure cors


What are the request options you are sending? Maybe it has to do something with that.

yuriney
FREEOP

5 months ago

curl -X OPTIONS -H "Origin: https://allcleanlaundry.onrender.com" -H "Access-Control-Request-Method: GET" -v "https://allcleanlaundry-production.up.railway.app/healthcheck"


smolpaw

Let me see the code where you configure cors

yuriney
FREEOP

5 months ago

package com.laundry.laundryservice.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://allcleanlaundry.onrender.com")
                .allowedMethods("*")
                .allowCredentials(true);
    }
}

yuriney

package com.laundry.laundryservice.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("https://allcleanlaundry.onrender.com") .allowedMethods("*") .allowCredentials(true); } }

smolpaw
HOBBY

5 months ago

Change your code to this and redeploy

public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://allcleanlaundry.onrender.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);

}

smolpaw

Change your code to this and redeploypublic void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("https://allcleanlaundry.onrender.com") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); }

yuriney
FREEOP

5 months ago

I've deployed it, and it is still forbidden:
HTTP/1.1 403 Forbidden

< Date: Fri, 06 Jun 2025 19:46:44 GMT

< Server: railway-edge


root101
HOBBY

5 months ago

Try a more general approach, use this config:

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(List.of("*"));
    configuration.setAllowedMethods(List.of("*"));
    configuration.setAllowedHeaders(List.of("*"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

2 things:

1 - This one allow all from all places, but hey, it's just a test, if it work, then configure it as your needs.

2 - Note how the config change, you are using an override on WebMvcConfigurer, this config rewrite the entire cors config bean.

This config is currently working for me.
Give it a try and let us know, if it doesn't work, maybe create a public repo with a Minimal Reproducible Example we can fork, deploy, and make you a PR with solution


yuriney
FREEOP

5 months ago

For some reason it is still forbiden.
here it is the piblic repo:
https://github.com/yuriney/AllCleanLaundry/tree/main/AllClean-backend/laundryservice


root101
HOBBY

5 months ago

Sorry, I didn't know you weren't using Spring Security.

WITHOUT Spring security, this is the correct config:

package com.laundry.laundryservice.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*");
    }
}

With Spring security is:

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(List.of("*"));
    configuration.setAllowedMethods(List.of("*"));
    configuration.setAllowedHeaders(List.of("*"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

I Just tested both and work as a charm... take a look and let us know (BTW, thanks for the repo, It was exactly what I needed to reproduce the problem)

NOTE: this is an experimental config allowing all origins, methods, headers; for a production environment I recommend you configure them appropriately


yuriney
FREEOP

5 months ago

Thanks for the note, I have pushed the suggested changes, and I find myself stuck on the same issue (403 Forbidden). I wonder if the error could be from railway proxy.


root101
HOBBY

5 months ago

It's working in local?
Can you sent a screenshot of the request in the console of the explorer? Because CORS can fail because of a couple of factors... this will help us to know for sure the error


root101

It's working in local?Can you sent a screenshot of the request in the console of the explorer? Because CORS can fail because of a couple of factors... this will help us to know for sure the error

yuriney
FREEOP

5 months ago

Yes, it is working in local

Attachments


yuriney

Yes, it is working in local

(Reposting Root's message)

Hey, no idea why it's not working, I just deploy your project, and made an request, and it's working great.

Back: Project deploy without problems

Front: I use an old page, rewrite the 'login' to made the request and print result, and it worked... Maybe is a problem with your client, I see you are using Vite + React, I have no idea how it work, and therefore, don't know how to fix it from the client side... Maybe try another client, make a test in another tech stack


Loading...