Forcing Collabora https through X-Forwarded-Proto or rewrite

1. The problem I’m having:

I am currently setting up Collabora for Nextcloud, where Collabara is currently displaying http ports in a .xml file because it believes I am connecting through http. While my Caddy proxy actually takes care of SSL. This makes Collabora not SSL encrypted since it displayes http ports to Nextcloud (and error in Nextcloud). To solve this a Collabara thread said that a requirement for overriding Collabara to give https is to pass on “X-Forwarded-Proto: https” or rewrite the scheme externally (which I don’t know how to approach) ( Am I misunderstanding ssl.termination and the discovery endpoint? - #2 by darshan - Installation & Configuration - Collabora Online ).

If anyone has any idea to solve this (not just X-Forwarded-Proto) then I would greatly appreciate that! As an aside, I read the logs which display ```“X-Forwarded-Proto”: [“https”]```, could it be that Collabora misinterperetes it due to it is an array?

2. Error messages and/or full log output:

````2026/02/16 23:43:22.649 DEBUG   http.handlers.reverse_proxy     upstream roundtrip      {"upstream": "host.containers.internal:9980", "duration": 0.001089047, "request": {"remote_ip": "192.168.39.110", "remote_port": "49799", "client_ip": "192.168.39.110", "proto": "HTTP/2.0", "method": "GET", "host": "office.mydomain.com", "uri": "/hosting/discovery", "headers": {"Accept-Encoding": ["gzip, deflate, br, zstd"], "Sec-Fetch-Dest": ["document"], "Sec-Fetch-User": ["?1"], "X-Forwarded-Host": ["office.mydomain.com"], "Te": ["trailers"], "X-Forwarded-For": ["192.168.39.110"], "Accept-Language": ["en-US,en;q=0.9"], "Upgrade-Insecure-Requests": ["1"], "Sec-Fetch-Site": ["none"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"], "Sec-Fetch-Mode": ["navigate"], "Via": ["2.0 Caddy"], "User-Agent": ["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:147.0) Gecko/20100101 Firefox/147.0"], "If-Modified-Since": ["Mon, 16 Feb 2026 23:36:46"], "Sec-Gpc": ["1"], "Priority": ["u=0, i"], "X-Forwarded-Proto": ["https"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "server_name": "office.mydomain.com"}}, "headers": {"Date": ["Mon, 16 Feb 2026 23:43:22"], "Server": [""], "Content-Length": ["32088"], "Content-Type": ["text/xml"], "Last-Modified": ["Mon, 16 Feb 2026 23:43:22"], "X-Content-Type-Options": ["nosniff"]}, "status": 200}
2026/02/16 23:43:22.650 INFO    http.log.access.log0    handled request {"request": {"remote_ip": "192.168.39.110", "remote_port": "49799", "client_ip": "192.168.39.110", "proto": "HTTP/2.0", "method": "GET", "host": "office.mydomain.com", "uri": "/hosting/discovery", "headers": {"Sec-Gpc": ["1"], "Upgrade-Insecure-Requests": ["1"], "Sec-Fetch-Site": ["none"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"], "Accept-Language": ["en-US,en;q=0.9"], "Sec-Fetch-User": ["?1"], "If-Modified-Since": ["Mon, 16 Feb 2026 23:36:46"], "Priority": ["u=0, i"], "Accept-Encoding": ["gzip, deflate, br, zstd"], "Sec-Fetch-Dest": ["document"], "User-Agent": ["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:147.0) Gecko/20100101 Firefox/147.0"], "Sec-Fetch-Mode": ["navigate"], "Te": ["trailers"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "server_name": "office.mydomain.com"}}, "bytes_read": 0, "user_id": "", "duration": 0.001805079, "size": 32088, "status": 200, "resp_headers": {"Content-Length": ["32088"], "Via": ["1.1 Caddy"], "Alt-Svc": ["h3=\":443\"; ma=2592000"], "Content-Type": ["text/xml"], "Last-Modified": ["Mon, 16 Feb 2026 23:43:22"], "X-Content-Type-Options": ["nosniff"], "Date": ["Mon, 16 Feb 2026 23:43:22"], "Server": [""]}}```

3. Caddy version:

v2.10.2

4. How I installed and ran Caddy:

Podman quadlet from alpine builder image with Porkbun acme_dns

a. System environment:

DietPi v10.0.1, arm64, systemd, Podman quadlet

b. Command:

``` podman run --name caddy --cidfile=/run/user/1003/caddy.cid --replace --rm --cgroups=split --sdnotify=conmon -it --cap-add net_admin -v /home/caddy/.config/containers/volumes/caddy/conf:/etc/caddy -v /home/caddy/.config/containers/volumes/caddy/data:/data --publish 1080:80/tcp --publish 1443:443/tcp --publish 1443:443/udp --secret porkbun-api-key,type=env,target=PORKBUN_API_KEY --secret porkbun-api-secret-key,type=env,target=PORKBUN_API_SECRET_KEY localhost/caddy```

c. Service/unit/compose file:

```
[Container]
ContainerName=caddy
Image=caddy.build

Volume=../../volumes/caddy/conf:/etc/caddy
Volume=../../volumes/caddy/data:/data

PublishPort=1080:80/tcp
PublishPort=1443:443/tcp
PublishPort=1443:443/udp

AddCapability=NET_ADMIN

Secret=porkbun-api-key,type=env,target=PORKBUN_API_KEY
Secret=porkbun-api-secret-key,type=env,target=PORKBUN_API_SECRET_KEY

[Service]
Restart=unless-stopped
# Pasta lack time to properly configure at boot, silly workaround:
ExecStartPre=/bin/sleep 20

[Install]
# Start by default on boot
WantedBy=default.target
```

d. My complete Caddy config:

```
{
        acme_dns porkbun {
                api_key {env.PORKBUN_API_KEY}
                api_secret_key {env.PORKBUN_API_SECRET_KEY}
        }
}

(ssl) {
        tls {
                dns porkbun {
                        api_key {env.PORKBUN_API_KEY}
                        api_secret_key {env.PORKBUN_API_SECRET_KEY}
                }
        }
}

http://office.mydomain.com, office.mydomain.com {
        reverse_proxy host.containers.internal:9980
        import ssl
}

cloud.mydomain.com {
        redir /.well-known/carddav /remote.php/dav/ 301
        redir /.well-known/caldav /remote.php/dav/ 301

        header {
                Strict-Transport-Security max-age=31536000;
        }

        reverse_proxy host.containers.internal:4080
        import ssl
}
```

5. Links to relevant resources:

No, all headers are array because a header can appear many times in a request/response and therefore have multiple values. But most of the time unless otherwise specified, some “getHeader” kind of function would just give you the first value.

Ultimately this is a Collabora bug because clearly Caddy it passing down the header as it should, so you’ll need to get help from them.