Backend API calls failing through Cloudflare tunnel setup

I set up a Cloudflare tunnel on my Linux machine to serve a web application. The tunnel has two public hostnames configured:

I used cloudflared tunnel route dns to configure the DNS settings.

My frontend makes API calls using axios:

export const fetchUserData = async () => {
  return await axios.post(`https://mysite.com/api/fetch-user-data`);
}

The Express server is set up like this:

const server = express();
const SERVER_PORT = 8080;

const corsConfig = {
  origin: [
    `http://localhost:3000`,
    `http://localhost:8080`,
    "https://mysite.com",
  ],
  optionsSuccessStatus: 200,
};

server.post("/api/fetch-user-data", Handler.fetchUserData);

server.listen(SERVER_PORT, () => {
  console.log(`Server running on port ${SERVER_PORT}`);
});

The frontend loads fine from the public internet, but API requests fail with:

POST https://mysite.com/api/fetch-user-data 404 (Not Found)

Testing curl -X POST http://localhost:8080/api/fetch-user-data locally works perfectly and returns the expected data. However, curl -X POST https://mysite.com/api/fetch-user-data returns nothing.

I tried adding a config.yml file in the .cloudflared directory but it did not help. What am I missing in my tunnel configuration?

Check your tunnel config order - Cloudflare processes routes sequentially, so your general mysite.com rule is probably catching everything before it gets to the api/* path. Swap the order or make your root domain routing more specific.

sounds like a routing issue with your tunnel setup. maybe double-check if your path matching is working right – try a simple GET endpoint first to see if api/* routes correctly. what do the Cloudflare tunnel logs say when you hit those endpoints?

I’ve seen this exact issue before. Your tunnel isn’t recognizing the api/* pattern properly. Don’t use the DNS route command for path routing - it’s unreliable. Set up a proper config.yml with explicit ingress rules instead. Put your most specific routes first, then the catch-all. Something like - hostname: mysite.com with path: /api/* pointing to http://localhost:8080, then your frontend rule below that. Restart the tunnel daemon after you update the config file.