CalDAV Sync Not Working on Mobile — Fix
The Problem
Your self-hosted CalDAV/CardDAV server (Radicale, Baikal, Davis, or EteSync) works in the browser or with desktop clients, but mobile devices won’t sync. Calendar events or contacts don’t appear on your iPhone or Android phone, or the account setup fails entirely.
The Cause
Mobile CalDAV/CardDAV clients are strict about URLs, SSL certificates, and service discovery. The most common causes: using the wrong URL format (each server has a different path structure), self-signed certificates that mobile OS rejects, missing .well-known redirects that clients depend on for auto-discovery, or authentication issues with special characters in passwords.
The Fix
Method 1: Use the Correct URL Format (Most Common)
Each CalDAV server uses a different URL path. Using the wrong format is the #1 cause of sync failures.
Radicale:
CalDAV: https://cal.example.com/username/calendar-name/
CardDAV: https://cal.example.com/username/contacts/
Baikal:
CalDAV: https://cal.example.com/dav.php/calendars/username/default/
CardDAV: https://cal.example.com/dav.php/addressbooks/username/default/
Davis:
CalDAV: https://cal.example.com/dav/calendars/username/default/
CardDAV: https://cal.example.com/dav/addressbooks/username/default/
EteSync (via bridge):
CalDAV: http://localhost:37358/
CardDAV: http://localhost:37358/
EteSync requires the EteSync-DAV bridge running locally on your phone or a server-side bridge.
iPhone (iOS): Go to Settings → Calendar → Accounts → Add Account → Other → Add CalDAV Account. Enter the server URL, username, and password.
Android: Use DAVx⁵ (recommended, available on F-Droid and Play Store). Enter the base URL and credentials. DAVx⁵ handles service discovery automatically.
Method 2: Fix .well-known Service Discovery
Many CalDAV clients try auto-discovery via .well-known URLs before using the URL you provide. If these aren’t configured, the client may fail silently.
Your reverse proxy needs to redirect:
/.well-known/caldav → /dav.php/ (Baikal)
/.well-known/carddav → /dav.php/ (Baikal)
Nginx example:
location /.well-known/caldav {
return 301 /dav.php/;
}
location /.well-known/carddav {
return 301 /dav.php/;
}
Caddy example:
cal.example.com {
redir /.well-known/caldav /dav.php/ 301
redir /.well-known/carddav /dav.php/ 301
reverse_proxy baikal:80
}
For Radicale, redirect to the root:
redir /.well-known/caldav / 301
redir /.well-known/carddav / 301
Method 3: Fix SSL Certificate Issues
Mobile devices reject self-signed certificates. You need a valid SSL certificate from Let’s Encrypt or another CA.
Check your certificate:
curl -v https://cal.example.com 2>&1 | grep "SSL certificate"
If you’re using Let’s Encrypt via your reverse proxy, ensure:
- The certificate covers your CalDAV subdomain
- The certificate isn’t expired
- The full chain is included (some Android versions need the intermediate certificate)
iPhone-specific: iOS completely refuses self-signed certificates for CalDAV. There’s no override — you must use a valid certificate.
Android with DAVx⁵: DAVx⁵ can accept self-signed certificates if you explicitly trust them, but a valid certificate is strongly recommended.
Method 4: Fix Authentication Issues
Special characters in passwords: Some mobile clients mishandle passwords with special characters (@, #, &, %). Try a password with only alphanumeric characters to test.
Basic auth vs digest auth: Most CalDAV servers use HTTP Basic authentication. Ensure your reverse proxy passes the Authorization header:
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
Baikal-specific: Baikal requires the Authorization header. If your reverse proxy strips it:
location / {
proxy_pass http://baikal:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Authorization $http_authorization;
}
Method 5: Check Server Logs
If none of the above work, check your CalDAV server’s logs for error details:
# Radicale
docker compose logs radicale
# Baikal
docker compose logs baikal
# Davis
docker compose logs davis
Look for authentication failures (401/403), path not found (404), or internal errors (500). The error code tells you exactly what’s wrong.
Prevention
- Always set up
.well-knownredirects when configuring your reverse proxy — prevents 80% of mobile sync issues - Use DAVx⁵ on Android — it’s the most reliable CalDAV/CardDAV client and handles auto-discovery well
- Use valid SSL certificates — Let’s Encrypt is free and automated
- Test with curl first before configuring mobile:
curl -u username:password https://cal.example.com/.well-known/caldav -v - Keep passwords simple initially — add complexity after sync is confirmed working
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments