Recently, I setup a self-hosted nextcloud instance, for my own personal use. One of the primary uses I had for this service, besides storing sharable content on the internet, was to have a central place where I stored and synced things like appointments, meetings, and tasks. That requires a working CALDAV and CARDDAV discovery service, and nextcloud has this feature, so I was eager to get it up and running.
Unfortunately, out of the box, it wasn’t working. I tried all sorts of suggestions which I culled from the internet, which involved modifying my apache config, adding explicit Redirect statements to htaccess files, and even moving files around. Nothing worked. Not even the documentation from nextcloud itself was any help.
Then, after a day of staring blankly at the problem, I suddenly realized what was wrong. There was a simple regex
typo in the htaccess configuration that came from nextcloud. Let’s see if you can see the difference. Here’s what nextcloud gives you:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} DavClnt
RewriteRule ^$ /remote.php/webdav/ [L,R=302]
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
RewriteRule ^remote/(.*) remote.php [QSA,L]
RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]
</IfModule>
and here is what I ended up running successfully with:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} DavClnt
RewriteRule ^$ /remote.php/webdav/ [L,R=302]
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^/\.well-known/carddav /remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/caldav /remote.php/dav/ [R=301,L]
RewriteRule ^remote/(.*) remote.php [QSA,L]
RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]
</IfModule>
Can you see it? Hint: RewriteRules require leading forward-slashes to work. But REGEX rules require leading back-slashes to escape special characters in uris. So, I had to change this ^\.
to this ^/\.
and everything started working.
Hopefully, for those of you into self-hosting, this will save you the hours of pain and suffering it cost me.