Caddy reverse proxy Spacebar Service

1. The problem I’m having:

The issue im having is hosting a new service on my server with a reverse proxy to that service. Ive run through someone on the support team for the application and we’ve got it narrowed down to a cors issue, or a header problem. Im posting the logs below which show an okay output, but when going to theres nothing being returned

2. Error messages and/or full log output:

luke@luke:~$ curl -vL
*   Trying
* Connected to ( port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject:
*  start date: Feb 15 03:37:25 2024 GMT
*  expire date: May 15 03:37:24 2024 GMT
*  subjectAltName: host "" matched cert's "*"
*  issuer: C=US; O=Google Trust Services LLC; CN=GTS CA 1P5
*  SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* Using Stream ID: 1 (easy handle 0x562e5b1b1eb0)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET / HTTP/2
> Host:
> user-agent: curl/7.81.0
> accept: */*
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 200 
< date: Tue, 26 Mar 2024 11:13:52 GMT
< content-type: text/html; charset=UTF-8
< access-control-allow-headers: *
< access-control-allow-headers: *
< access-control-allow-methods: *
< access-control-allow-methods: *
< access-control-allow-origin: *
< access-control-allow-origin: *
< alt-svc: h3=":443"; ma=86400
< cache-control: public, max-age=0
< content-security-policy: default-src *  data: blob: filesystem: about: ws: wss: 'unsafe-inline' 'unsafe-eval'; script-src * data: blob: 'unsafe-inline' 'unsafe-eval'; connect-src * data: blob: 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; frame-src * data: blob: ; style-src * data: blob: 'unsafe-inline'; font-src * data: blob: 'unsafe-inline';
< last-modified: Tue, 26 Mar 2024 09:49:08 GMT
< vary: Accept-Encoding
< x-powered-by: Express
< cf-cache-status: DYNAMIC
< report-to: {"endpoints":[{"url":"https:\/\/\/report\/v4?s=x2MLAKWNYN5OMyHHCVmA95eS4KTijHJGm9UGQ3NESRakAFnxAiAn%2FOC9HxDhRC9xD4MvktSdk%2BKeE%2F5zcAqqgpm3cE6w7TNDZGbHQ%2BTaCUYiMOVfj3VaPG%2BIxr7tIXsiLSPu0X7%2BcvodHjTW"}],"group":"cf-nel","max_age":604800}
< nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
< server: cloudflare
< cf-ray: 86a6b6bf4afe9551-LHR
* TLSv1.2 (IN), TLS header, Supplemental data (23):
<!DOCTYPE html>
<html lang="en">

        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Spacebar Server</title>

        <link rel="preconnect" href="">
        <link rel="preconnect" href="" crossorigin>
        <link href="" rel="stylesheet">

                body {
                        font-family: 'Montserrat', sans-serif;
                        background-color: rgb(10, 10, 10);
                        color: white;
                        font-size: 1.1rem;
                        height: 100vh;

                * {
                        padding: 0;
                        margin: 0;

                p {
                        margin-top: 10px;

                .container {
                        display: flex;
                        flex-direction: column;
                        justify-content: center;
                        align-items: center;
                        margin: 0 40px 0 40px;
                        height: 100%;

                #wordmark {
                        width: min(500px, 50%);
                        margin-bottom: 20px;

                a, a:visited {
                        color: #0185ff;

        <div class="container">
                <img alt="Spacebar Logo"
                        src="" />

                <p>If you're viewing this page, that means you've successfully set up your very own Spacebar instance!</p>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
                <p>For information on how to configure your shiny new setup, you should visit <a href="">our documentation</a></p>
                <p>For information on how to connect and use your instance, <a href="">click here</a></p>

* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection #0 to host left intact

3. Caddy version:

luke@luke:~$ caddy version
v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

4. How I installed and ran Caddy:

a. System environment:

I ran and installed caddy using the documentation provided here. Im using Ubuntu as my OS, and the service is running via systemd

b. Command:

sudo systemctl start caddy

c. Service/unit/compose file:

d. My complete Caddy config: {
    reverse_proxy / {
        header_up Host {host}
        header_up X-Real-IP {remote}
        header_up X-Forwarded-Proto "https"
        header_up X-Forwarded-For {remote}
        header_up X-Forwarded-Host {host}

    encode zstd gzip
  header {
    Access-Control-Allow-Headers *
    Access-Control-Allow-Methods *
    Access-Control-Allow-Origin *
  @options {
    method OPTIONS
  respond @options 204

5. Links to relevant resources:

Remove all this, it’s not useful. Caddy sets proxy headers appropriately, automatically.

Your problem here is the / matcher, which matches only / and nothing else. Remove that /.

Are you sure you need this? In general, CORS is an application-level concern. You shouldn’t need to do this in your webserver if you’re proxying to an app.

Ah okay ive removed the slash from the caddy file and thats now sending data properly, im still receiving errors around the app but the return is something now at least

Im not sure if i need cors, its mentioned quite often in their discord, and by the maintainers when i chatted to them. I initially was receiving errors around cors that im no longer getting

The photograph above with show the errors im now receiving when trying to login

This is the site you use to login using their react app

This is the instance

If you open dev tools youll see that error

What’s your Caddyfile at this point?

Like I said, CORS is an application-level issue, not a server-level issue. The app you proxy to should set the CORS headers as necessary.