From Tom AI: Yeah that makes sense — this is SparkBox's own domain wizard code, and it looks like it only does HTTP challenge right now, not DNS challenge. The logs earlier showed Failed to set up domain errors coming from domain-wizard.js, which lines up exactly with this. This is genuinely a SparkBox limitation when your DNS points to a private/Tailscale IP. Tom needs to add Cloudflare DNS challenge support to the wizard. I'm adding them through nginx proxy host, instead.
19 replies
tomspark wrote:
You diagnosed it exactly right. The domain wizard only does the HTTP challenge today, so it can't finish when your domain points at a private/Tailscale IP. Adding them through the nginx proxy host directly, like you're doing, is the correct workaround for now and will keep working fine. I've flagged adding the DNS-challenge path to the wizard so this works out of the box down the line. Appreciate you digging through the logs on this one.
kiltmann wrote:
I ended up breaking Nginx. I deleted the hosts and certificates thinking I could just redo them. Turns out, I can't. Thoughts?
tomspark wrote:
No worries, nothing's permanently broken. The reason you can't recreate them is the certificate step, not the hosts themselves: for a private/Tailscale address the automatic certificate can't verify, so NPM fails right at that point. To get un-stuck, re-add each proxy host but set SSL to None for now, they'll save cleanly and your apps are reachable again. The certificate-for-private-addresses piece is the exact limitation we're adding proper support for, so you can switch SSL back on once that lands. Want me to walk through re-adding one step by step?
kiltmann wrote:
Thanks! I think I can do it. I just get internal error each time I add them back.
tomspark wrote:
You're not broken — that internal error is the proxy manager still tripping over the leftover config from when you deleted everything. Easiest reset is to restart just that one container so it rebuilds clean. SSH into the NAS and run: docker restart sb-npm Give it about 30 seconds, then go back to the proxy host screen and add it again with SSL set to None. It should save without the error this time. If it still pops up, tell me and I'll walk you through the next step.
kiltmann wrote:
I think I'm stuck and Nginx has to be removed and rebuild clean. I click on the proxy hosts I've created and I get error 521 or 525, server unavailable. I went into cloudflare console and messed about in there, removing the tunnel, changing the SSL/TSL encryption, and a whole bunch of other things AI platforms suggested. I port forwarded my eero to 80 and 443 with my server IP (static), and they show as green. Thoughts?
tomspark wrote:
You're not stuck for good — those 521 and 525 errors are actually a useful clue. They only show up when Cloudflare is sitting in front of your server (the cloud icon next to your domain is orange) and can't reach your box. So right now it's Cloudflare blocking you, not SparkBox or Nginx. Try this: in Cloudflare, open your DNS records, find your domain's record, and click the orange cloud so it turns grey ('DNS only'). Wait a minute, then reload. Grey cloud sends traffic straight to your server and skips the part that's failing. If you'd rather drop the whole domain and Cloudflare hassle, Tailscale reaches your apps with no ports and no certificates at all — say the word and I'll point you there.
kiltmann wrote:
I have tailscale running on my server and several devices on my tailnet. I was having trouble setting things up with cloudflare and tailscale. What I read, too, was since I have a free tailscale account, they don't like if one is streaming a lot of data. I have crowdsec running baremetal, too. What I was hoping to do was be able to connect anywhere I am to my server and apps. I also wanted to be able to let family and friends have access to navidrome, audiobookshelf, jellyfin, and seer. At work, the wifi does not allow tailscale, though, so I have to use my phone hotspot. Thoughts?
tomspark wrote:
Good news — you're closer than it feels. Two parts: For reaching your own apps from anywhere: Tailscale already does that, and don't sweat the streaming limit — when your phone connects to your server they talk directly, so your media isn't going through Tailscale or counting against anything. Work WiFi blocking it is the one gap, and your hotspot is the right workaround. For family and friends: the easiest is Tailscale's 'share' feature — you share your server with their account, they install the app once, and Jellyfin and Navidrome just work, no domain or certificates needed. The public-link route you tried also works but it's fiddly and exposes your server, so I'd only go there if 'install one app' is a dealbreaker for them. Want me to walk through sharing one with a friend?
kiltmann wrote:
I'd like it if I didn't have to use my data via my hotspot at work, and just use the wifi. I guess I am assuming that I would be able to reach my apps.personaldomain.net over wifi, though. Knowing my friends and family, unfortunately, I think they would probably have problems installing the tailscale app and understanding when and how to use it to get to things on my server. What is the best solution do you think?
tomspark wrote:
Then the domain route is your best bet — it solves both at once: your apps on a real web address work over any network (work WiFi, no hotspot), and friends just click a link with nothing to install. What tripped you up before was the certificate failing, and that only happened because the domain pointed at your private Tailscale address. Now that ports 80 and 443 are forwarded, point the domain's DNS straight at your home's public IP (on Cloudflare, the grey 'DNS only' cloud), then in Nginx add the host and request a new certificate — it should work this time since it can finally reach your server. Since these will be public, keep CrowdSec on and use each app's own login. Want me to walk through one app end to end?
kiltmann wrote:
In cloudflare, I have the dns set to my home's public IP, Grey DNS Only Clouds, and two A records one with a domain.net and one with just domain.net. There are three other text type records suggested for security by cloudflare. Zero trust is off (I think). What do I do in Nginx? Thank you for your help!
tomspark wrote:
Here's Jellyfin end to end — the others follow the same pattern. In Nginx Proxy Manager: Hosts - Proxy Hosts - Add Proxy Host. On the Details tab: - Domain Names: watch.yourdomain.net - Scheme: http - Forward Hostname/IP: sb-jellyfin-media - Forward Port: 8096 - Turn on 'Websockets Support' (Jellyfin needs it) Then the SSL tab: choose 'Request a new SSL Certificate', turn on 'Force SSL', agree to the terms, and Save. It'll fetch the certificate — that's the exact step that failed before, and it'll work now that the domain reaches your server. Jellyfin's then live at watch.yourdomain.net. Same pattern for the rest, just swap the name and port: Navidrome sb-navidrome:4533, Audiobookshelf sb-audiobookshelf:80, Seerr sb-seerr:5055. Yell if the certificate step throws an error.
kiltmann wrote:
The certificate step shows internal error.
tomspark wrote:
Internal error is annoyingly vague — but the real reason is sitting in Nginx Proxy Manager's log. Right after it fails, SSH into the server and run: sudo docker logs sb-npm --tail 30 Paste me the last several lines and I'll tell you exactly what's blocking the certificate. It's usually one of two things — leftover state from the earlier resets, or your home internet provider quietly blocking the port the certificate check needs (more common than people expect). The log will say which.
kiltmann wrote:
I've removed my email address below: [6/1/2026] [3:51:58 PM] [IP Ranges] › ℹ info IP Ranges Renewal Timer initialized [6/1/2026] [3:51:58 PM] [SSL ] › ℹ info Completed SSL cert renew process [6/1/2026] [3:51:58 PM] [Global ] › ℹ info Backend PID 208 listening on port 3000 ... [6/1/2026] [4:30:09 PM] [Remote Version] › ℹ info Fetching https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest [6/1/2026] [4:31:47 PM] [Nginx ] › ℹ info Reloading Nginx [6/1/2026] [4:31:47 PM] [SSL ] › ℹ info Requesting LetsEncrypt certificates for Cert 19: watch.celestialhub.net [6/1/2026] [4:31:47 PM] [SSL ] › ℹ info Command: certbot certonly --config /etc/letsencrypt.ini --work-dir /tmp/letsencrypt-lib --logs-dir /data/logs --cert-name npm-19 --agree-tos --authenticator webroot -m @gmail.com --preferred-challenges http --domains watch.celestialhub.net [6/1/2026] [4:31:51 PM] [Nginx ] › ℹ info Reloading Nginx [6/1/2026] [4:31:51 PM] [Express ] › ⚠ warning Saving debug log to /data/logs/letsencrypt.log Some challenges have failed. Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /data/logs/letsencrypt.log or re-run Certbot with -v for more details. [6/1/2026] [4:33:22 PM] [Nginx ] › ℹ info Reloading Nginx [6/1/2026] [4:33:22 PM] [SSL ] › ℹ info Requesting LetsEncrypt certificates for Cert 20: jellyfin.celestialhub.net [6/1/2026] [4:33:22 PM] [SSL ] › ℹ info Command: certbot certonly --config /etc/letsencrypt.ini --work-dir /tmp/letsencrypt-lib --logs-dir /data/logs --cert-name npm-20 --agree-tos --authenticator webroot -m @gmail.com --preferred-challenges http --domains jellyfin.celestialhub.net [6/1/2026] [4:33:28 PM] [Nginx ] › ℹ info Reloading Nginx [6/1/2026] [4:33:28 PM] [Express ] › ⚠ warning Saving debug log to /data/logs/letsencrypt.log Some challenges have failed. Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /data/logs/letsencrypt.log or re-run Certbot with -v for more details. [6/1/2026] [4:51:58 PM] [SSL ] › ℹ info Renewing SSL certs expiring within 30 days ... [6/1/2026] [4:51:58 PM] [SSL ] › ℹ info Completed SSL cert renew process [6/1/2026] [5:51:58 PM] [SSL ] › ℹ info Renewing SSL certs expiring within 30 days ... [6/1/2026] [5:51:58 PM] [SSL ] › ℹ info Completed SSL cert renew process [6/1/2026] [6:51:58 PM] [SSL ] › ℹ info Renewing SSL certs expiring within 30 days ... [6/1/2026] [6:51:58 PM] [SSL ] › ℹ info Completed SSL cert renew process [6/1/2026] [7:51:58 PM] [SSL ] › ℹ info Renewing SSL certs expiring within 30 days ... [6/1/2026] [7:51:58 PM] [SSL ] › ℹ info Completed SSL cert renew process [6/1/2026] [8:51:58 PM] [SSL ] › ℹ info Renewing SSL certs expiring within 30 days ... [6/1/2026] [8:51:58 PM] [SSL ] › ℹ info Completed SSL cert renew process
tomspark wrote:
That log pins it: the certificate check is trying to reach your server on port 80, and the knock isn't getting through ('challenges have failed'). That's almost always your home internet provider quietly blocking port 80 — really common, and nothing you can fix on the SparkBox side. Good news, there's a way around it that skips port 80 entirely. In Nginx, on that same SSL tab, instead of the normal request choose 'Use a DNS Challenge', pick Cloudflare, and paste a Cloudflare API token (you make one at Cloudflare - My Profile - API Tokens, allowed to edit DNS for your domain). That proves you own the domain through Cloudflare instead of knocking on port 80, so the certificate issues even with 80 blocked. Want the exact token permissions?
kiltmann wrote:
Yes, please. That would be great!
Chris wrote:
You said yes to this and then nobody came back to you — that one is on us, and I am sorry it sat this long. The good part: the thing you were waiting for shipped the very next day. SparkBox's own Custom Domains wizard now does the DNS challenge itself, so you do not have to hand-drive it in Nginx. It skips port 80 entirely, which is exactly what was blocking your certificate. On the box run sudo sparkbox upgrade (upgrade, not update — update only refreshes app images). Then in the dashboard open Settings, then Domains, tick the DNS-challenge option, choose Cloudflare and paste your API token there. Keep that token in the dashboard, never in a post here. Do one hostname at a time. — Chris