DISCLAIMER: Written by ChatGPT because I’m just too tired. But everything in here is based on what I actually did to make it finally work, and I’m sharing this in the hopes that it saves you some of the frustration I went through.
Introduction
So you’re self-hosting Joplin Server behind a Caddy reverse proxy and thought “Hey, I’ll just use tls internal, and it’ll all be fine.”
Spoiler: it won’t. Not right away, anyway.
This guide walks through exactly how to get Joplin Desktop to stop throwing cert errors (UNABLE_TO_GET_ISSUER_CERT_LOCALLY) and finally sync with your Joplin Server instance over HTTPS, using Caddy’s tls internal feature.
My Setup
- OS: Linux (Proxmox LXC running Docker)
- Reverse Proxy: Caddy with
tls internal - Joplin Server: Docker container (
joplin/server:latest) - Joplin Desktop: Windows client
- Domain:
joplin.YOUR_DOMAIN.com(local-only via internal DNS)
The Problem
Joplin Desktop does not trust certificates generated by Caddy’s internal CA out of the box. Even if:
- You’ve installed the root cert into Windows
- You’ve set the
NODE_EXTRA_CA_CERTSenvironment variable - You’ve tried
--ignore-certificate-errors - You’ve tested with
curloropenssland everything seems fine
…Joplin will still throw:
UNABLE_TO_GET_ISSUER_CERT_LOCALLY
Why? Because the Joplin client does not use your system’s CA trust store for internal requests.
The Solution
You have to explicitly point the Joplin Desktop app to the root certificate under:
Tools → Options → Synchronization → Show Advanced Settings → Custom TLS certificates
Yes, this setting is collapsed by default. Yes, it will drive you mad. Yes, it’s the only thing that works.
Step-by-Step Guide
1. Use tls internal in your Caddyfile
joplin.YOUR_DOMAIN.com {
reverse_proxy YOUR_IP_ADDRESS:YOUR_PORT
encode gzip
tls internal
log {
output file /var/log/caddy/notes.log
}
}
2. Find the Caddy root certificate
The Caddy root cert lives here:
/var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt
3. Copy the root certificate to your Windows machine
Save it somewhere easy to find, like:
C:\certs\caddy.crt
(If you’re using Notepad++ or similar, make sure line endings are preserved and the file isn’t mangled.)
4. Configure Joplin Desktop to trust the cert
- Open Joplin Desktop
- Go to Tools → Options → Synchronization
- Choose Joplin Server (Beta)
- Enter your server URL and credentials
- Click Show Advanced Settings
- Set
Custom TLS certificatesto:
C:\certs\caddy.crt
- Click Check synchronization configuration
If everything is working, you should get:
Success! Synchronization configuration appears to be correct.
5. Profit 🎉
Now you can sync across devices without needing to use http://, disable TLS, or punch holes in security you actually want.
Troubleshooting
Q: I already installed the cert in Windows. Why didn’t it work?
A: Joplin doesn’t use the Windows CA store for API calls. It only affects the embedded Chromium engine (UI stuff).
Q: What about NODE_EXTRA_CA_CERTS?
A: Joplin uses Electron/Node in a way that bypasses that setting for its sync requests.
Q: Why didn’t you mention this earlier?
A: Because I didn’t know. Now I do, and so do you.
Conclusion
Don’t trust the default. Don’t assume the CA store is enough. Don’t assume that just because curl says it’s good, Joplin will agree.
And above all, don’t skip over the hidden “Advanced Settings” button. It’s hiding the only thing that matters.
Stay sane out there.
If you got here because of a desperate late-night search — welcome. You’re not alone. Hopefully this helped.