The Problem
Joplin desktop or mobile app won't sync with your self-hosted Joplin Server. Common symptoms:
Completed: 25/02/2026 10:30
Last error: Error: ECONNREFUSED 127.0.0.1:22300
Sync failed: Could not connect to Joplin Server. Please check the Synchronisation options.
Or sync starts but items fail with 401/403 errors, notes don't appear on other devices, or sync gets stuck showing "Synchronizing..." indefinitely.
The Cause
Joplin Server sync requires the desktop/mobile client to reach the server over HTTPS, authenticate successfully, and have matching sync target configuration. The most common failure points:
- Wrong sync target URL in the client — must include the full path and use the external URL
- Sync target type not set to "Joplin Server" — Joplin defaults to Dropbox, not self-hosted
- Reverse proxy not forwarding correctly — WebSocket or large request blocking
- PostgreSQL connection issues — server can't reach its database
- SSL certificate problems — self-signed certs rejected by the client
The Fix
Method 1: Configure the Client Correctly (Most Common)
In the Joplin desktop app, go to Tools → Options → Synchronization and set:
| Setting | Value |
|---|---|
| Synchronization target | Joplin Server (not Joplin Cloud, not WebDAV) |
| Joplin Server URL | https://joplin.example.com |
| Joplin Server email | Your user email (the one you created in the admin panel) |
| Joplin Server password | Your user password |
Common mistakes:
| Wrong | Right |
|---|---|
http://192.168.1.100:22300 |
https://joplin.example.com (use the external URL) |
| Sync target: "Joplin Cloud" | Sync target: "Joplin Server" |
| Sync target: "WebDAV" | Sync target: "Joplin Server" |
URL with trailing slash: https://joplin.example.com/
|
https://joplin.example.com (no trailing slash) |
After changing settings, click Check synchronization configuration to test the connection.
Method 2: Verify the Server Is Running
Check that Joplin Server is healthy:
# Check container status
docker compose ps
# Check server logs for errors
docker compose logs joplin-server --tail=50
# Test the API endpoint
curl -v https://joplin.example.com/api/ping
# Should return: {"status":"ok","message":"Joplin Server is running"}
If the container is restarting, check the logs for database connection errors (see Method 4).
Method 3: Fix Reverse Proxy Configuration
Joplin Server requires WebSocket support and handles large sync payloads. Your reverse proxy must allow both.
Nginx Proxy Manager: Ensure WebSocket support is enabled in the proxy host settings.
Nginx manual config:
server {
listen 443 ssl;
server_name joplin.example.com;
client_max_body_size 200M; # Required for large note attachments
location / {
proxy_pass http://127.0.0.1:22300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Caddy:
joplin.example.com {
reverse_proxy localhost:22300
}
Caddy handles WebSocket and large bodies automatically.
Key checks:
-
client_max_body_size(Nginx) must be large enough for attachments (200M recommended) - WebSocket upgrade headers must be forwarded
- The proxy must not timeout long sync operations (set
proxy_read_timeout 300s;)
Method 4: Fix PostgreSQL Connection
If the server logs show database errors:
Error: connect ECONNREFUSED 127.0.0.1:5432
error: password authentication failed for user "joplin"
Verify your database configuration:
services:
joplin-server:
image: joplin/server:3.5.2
environment:
APP_BASE_URL: https://joplin.example.com
APP_PORT: 22300
DB_CLIENT: pg
POSTGRES_HOST: joplin-db # Must match the PostgreSQL service name
POSTGRES_PORT: 5432
POSTGRES_DATABASE: joplin
POSTGRES_USER: joplin
POSTGRES_PASSWORD: strongpass # Must match the database service
depends_on:
joplin-db:
condition: service_healthy
restart: unless-stopped
joplin-db:
image: postgres:16-alpine
environment:
POSTGRES_USER: joplin
POSTGRES_PASSWORD: strongpass
POSTGRES_DB: joplin
volumes:
- joplin-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U joplin"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
Ensure POSTGRES_HOST is the service name (joplin-db), not localhost.
Method 5: Fix SSL Certificate Issues
If the client shows SSL errors or sync fails with "certificate" in the error:
Self-signed certificates: The Joplin desktop app may reject self-signed certs. Go to Tools → Options → Synchronization → Advanced → Ignore TLS certificate errors and enable it (development only).
Let's Encrypt: If using a reverse proxy with Let's Encrypt, ensure the cert covers joplin.example.com. Test with:
curl -I https://joplin.example.com
# Check for: HTTP/2 200 and valid certificate
Internal network without SSL: If Joplin Server is only accessible on your LAN, use http:// in the sync URL and set APP_BASE_URL to match. However, sync over unencrypted HTTP is not recommended.
Method 6: Create a User Account
The default admin account is for server management, not syncing. Create a dedicated user:
- Open
https://joplin.example.comin a browser - Log in with the admin credentials (default:
admin@localhost/admin) - Go to Admin → Users → Add User
- Create a user with an email and password
- Use this email and password in the Joplin desktop app sync settings
If you're trying to sync with the admin account and it fails, create a regular user instead.
Prevention
- Always use the external HTTPS URL (not
localhost:22300) in the client sync settings - Set the sync target to "Joplin Server" — not "Joplin Cloud" or "WebDAV"
- Add a healthcheck on PostgreSQL so the server waits for the database
- Set
client_max_body_sizeto 200M+ in your reverse proxy - Test sync with
Check synchronization configurationafter any config change - Create a regular user for syncing — don't use the admin account
Top comments (0)