NO IP, Caddy, Jellyfin, Raspberry - No Certificate

1. The problem I’m having:

I want to access jellyfin from remote by adding caddy as reverse proxy on a raspberry PI4 with raspberryOS 64bit lite. I don’t get the certificate, when running caddy. See logs

2. Error messages and/or full log output:

`
Jan 19 17:13:09 xxxxx caddy[829]: {“level”:“error”,“ts”:1768839189.8486156,“logger”:“tls.obtain”,“msg”:“could not get certificate from issuer”,“identifier”:“xxxxx.ddns.net”,“issuer”:“acme-v02.api.letsencrypt.org-directory”,“error”:“HTTP 400 urn:ietf:params:acme:error:connection - 92.116.66.18: Fetching http://xxxxx.ddns.net/.well-known/acme-challenge/SUyR4Tek4Pgjs6dXAsz3D1HE5qVIvSsRRvzY9moefNc: Error getting validation data”}Jan 19 17:13:09 xxxxx caddy[829]: {“level”:“error”,“ts”:1768839189.8487456,“logger”:“tls.obtain”,“msg”:“will retry”,“error”:“[xxxxx.ddns.net] Obtain: [xxxxx.ddns.net] solving challenge: xxxxx.ddns.net: [xxxxx.ddns.net] authorization failed: HTTP 400 urn:ietf:params:acme:error:connection - 92.116.66.18: Fetching http://xxxxx.ddns.net/.well-known/acme-challenge/SUyR4Tek4Pgjs6dXAsz3D1HE5qVIvSsRRvzY9moefNc: Error getting validation data (ca=https://acme-staging-v02.api.letsencrypt.org/directory)”,“attempt”:3,“retrying_in”:120,“elapsed”:189.998216537,“max_duration”:2592000}
`

3. Caddy version:

v2.10.2 h1:g/gTYjGMD0dec+UgMw8SnfmJ3I9+M2TdvoRL/Ovu6U8=

4. How I installed and ran Caddy:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf ‘https://dl.cloudsmith.io/public/caddy/stable/gpg.key’ | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

curl -1sLf ‘https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt’ | sudo tee /etc/apt/sources.list.d/caddy-stable.list

chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg

chmod o+r /etc/apt/sources.list.d/caddy-stable.list

sudo apt update

sudo apt install caddy

a. System environment:

Raspberry PI4 with Raspberry OS Trixie, Caddy, Jellyfin

b. Command:

sudo systemctl status caddy
sudo systemctl start caddy
sudo systemctl stop caddy
sudo systemctl restart caddy
journalctl -f -u caddy

c. Service/unit/compose file:

No Docker

d. My complete Caddy config:

# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.
{
        admin :2020
}
#:80 {
        # Set this path to your site's directory.
#       root * /usr/share/caddy

        # Enable the static file server.
#       file_server

        # Another common task is to set up a reverse proxy:
        # reverse_proxy localhost:8080

        # Or serve a PHP site through php-fpm:
        # php_fastcgi localhost:9000
#}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile

xxxxx.ddns.net {
    # Reverse proxy to Jellyfin's internal address and port
    reverse_proxy 127.0.0.1:8096

    # Optional: Redirect HTTP to HTTPS (Caddy does this automatically)
    # header Strict-Transport-Security max-age=31536000;

    # Optional: Enable compression for faster streaming
    # encode gzip zstd

    # Optional: Set a custom port if needed (e.g., 443 for standard HTTPS)
    # tls {
    #     protocols tls1.2 tls1.3
    # }
}


5. Links to relevant resources:

1 Like

actual status… I configured the NO-IP Domain a little bit.

Now that is the actual log of caddy

Jan 19 20:47:59 xxxxx caddy[1482]: {"level":"info","ts":1768852079.5195818,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"xxxxx.ddns.net"}
Jan 19 20:47:59 xxxxx caddy[1482]: {"level":"info","ts":1768852079.5243683,"logger":"http","msg":"using ACME account","account_id":"https://acme-staging-v02.api.letsencrypt.org/acme/acct/259022443","account_contact":[]}
Jan 19 20:48:00 xxxxx caddy[1482]: {"level":"error","ts":1768852080.8859663,"msg":"validating authorization","problem":{"type":"urn:ietf:params:acme:error:rateLimited","title":"","detail":"Service busy; retry later.","instance":"","subproblems":null},"order":"https://acme-staging-v02.api.letsencrypt.org/acme/order/259022443/30798577453","attempt":1,"max_attempts":3,"stacktrace":"github.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.1.2/client.go:152\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.24.0/acmeissuer.go:489\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.24.0/acmeissuer.go:382\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.10.2/modules/caddytls/acmeissuer.go:288\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.24.0/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.24.0/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.24.0/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.24.0/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).manageOne.func1\n\tgithub.com/caddyserver/certmagic@v0.24.0/config.go:415\ngithub.com/caddyserver/certmagic.(*jobManager).worker\n\tgithub.com/caddyserver/certmagic@v0.24.0/async.go:73"}
Jan 19 20:48:00 xxxxx caddy[1482]: {"level":"error","ts":1768852080.8864136,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"xxxxx.ddns.net","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 503 urn:ietf:params:acme:error:rateLimited - Service busy; retry later."}
Jan 19 20:48:00 xxxxx caddy[1482]: {"level":"error","ts":1768852080.8865397,"logger":"tls.obtain","msg":"will retry","error":"[xxxxx.ddns.net] Obtain: [xxxxx.ddns.net] solving challenge: getting authorization at https://acme-staging-v02.api.letsencrypt.org/acme/authz/259022443/21265697503: attempt 3: https://acme-staging-v02.api.letsencrypt.org/acme/authz/259022443/21265697503: HTTP 503 urn:ietf:params:acme:error:rateLimited - Service busy; retry later. (ca=https://acme-staging-v02.api.letsencrypt.org/directory)","attempt":3,"retrying_in":120,"elapsed":189.95024049,"max_duration":2592000}
1 Like

Hi there!

The second error you are seeing (HTTP 503 … Service busy) is likely a temporary issue with the Let’s Encrypt Staging environment or a result of too many retries. It usually resolves itself if you wait a bit.

However, the first log shows the real problem that needs to be fixed:

Error getting validation data … HTTP 400 urn:ietf:params:acme:error:connection

This means Let’s Encrypt attempted to connect to your Raspberry Pi on Port 80 to validate your domain, but the connection failed. Since you are running this at home with No-IP, this is usually caused by one of two things:

Port Forwarding: Have you logged into your home router and forwarded ports 80 and 443 to the internal IP address of your Raspberry Pi? Without this, traffic from the internet hits your router and stops there.

Firewall / ISP: Check if your Raspberry Pi’s firewall (ufw or iptables) allows incoming traffic on ports 80/443. Also, ensure your ISP allows you to open ports (some ISPs use CGNAT, which prevents port forwarding).

To test this: Try to access your domain from a device outside your home network (like your phone on 4G/5G). If you cannot load a page (even an empty one), Let’s Encrypt can’t reach you either.

Hello @pauloappbr

thank you for your answer. I did everything you wrote before and it didn’t work.

Yesterday I was so desperate, that I delete the NO IP domain, created a new one under NO IP, started caddy with

“caddy reverse-proxy --from example.com --to 127.0.0.1:8096”

and once it got the certificate. Now it is running.

I didn’t change anything with the ports, after I allowed everything on router and raspberry.

Thanks a lot fo confirmation and help

Case closed :smiley:

OK, I did not see the problem. The command worked once for me an therefor not anymore.

Now I found the crucial difference.

I seem to started the command not like described on the jellyfin page

with

caddy reverse-proxy --from example.com --to 127.0.0.1:8096

but with

sudo caddy reverse-proxy --from example.com --to 127.0.0.1:8096

So what do I have to do that caddy starts with sudo my configuration

xxxxx.ddns.net {
    # Reverse proxy to Jellyfin's internal address and port
    reverse_proxy 127.0.0.1:8096

    # Optional: Redirect HTTP to HTTPS (Caddy does this automatically)
    # header Strict-Transport-Security max-age=31536000;

    # Optional: Enable compression for faster streaming
    # encode gzip zstd

    # Optional: Set a custom port if needed (e.g., 443 for standard HTTPS)
    # tls {
    #     protocols tls1.2 tls1.3
    # }
}

Thanks again