Nextcloud behind reverse Apache proxy - 401 unauthorized

After years of running Owncloud (in a FreeNAS jail, version 9.1.2 - yep, old!), I’ve decided to move to Nextcloud and run it on a dedicated VM on ESXi. Access to both from the outside world is through an Apache reverse proxy which also provides SSL; this has been working well for years with Owncloud. Clients are both web browsers and WebDAV (the Owncloud windows client, the Owncloud or Nextcloud android client, and a third-party Android app that records phone calls and automatically uploads them).

I grabbed the pre-built Nextcloud VM from HanssonIT and went through the installation. Then configured the apache reverse proxy and tweaked the Nextcloud config.php. Web access works exactly as expected.

However, it seems that all WebDAV fails authentication.

  • Pointing a web browser to the WebDAV URL just recycles asking for authentication info ( [works fine with https://www.example/com/owncloud/remote.php/webdav)
  • Attempting to mount a Windows folder through Explorer (the Windows WebDAV client) fails.
  • Attempting to connect via the Nextcloud Android client fails. It does go through the “authorizing your device” bit, and each attempt creates another entry under “devices and sessions” as seen from the web client under ‘settings’. The android client does note at the bottom of the screen that the response was ‘401 unauthorized’, although the credentials that are being used are correct.

Obviously, it’s something with either the proxy config or how Nextcloud deals with the proxy. I figure it’s unlikely that this is a bug.

Nextcloud version: 17.0.2
Operating system and version: Ubuntu 18.04.3
Apache version: 2.4.29
PHP version: 7.2.24
Apache version on proxy: 2.2.15

The output of your Nextcloud log in Admin > Logging:

Nothing shows in the logs... no auth errors etc.

The output of your config.php file in /path/to/nextcloud (make sure you remove any identifiable information!):

  'trusted_proxies' => [''],
  'overwritehost' => '',
  'overwriteprotocol' => 'https',
  'overwritewebroot' => '/nextcloud',
  'overwrite.cli.url' => '',     #not sure i need this?

Apache proxy configuration snippet

ProxyPass /nextcloud http://ip.of.nextcloud.server/nextcloud
ProxyPassReverse /nextcloud http://ip.of.nextcloud.server/nextcloud

I’m at a loss as to where to look further. Nothing stands out to me in either the Nextcloud Apache2 logs or the logs on my reverse proxy.

Thinking that the problem might be my antique proxy, I spun up a new VM (CentOS 8) with Apache 2.4.37. Super generic config, and reverse proxying the same way.

Same problem; regular access via web browser works great, but Webdav fails.

Which makes me think this is either

  • Some config setting I’m missing on the proxy
  • Some config setting that I’m missing on Nextcloud
  • A bug in Nextcloud? Nah, couldn’t be?

Turned on debug logging in Nextcloud, and it appears that Nextcloud is not getting the username/password that is passed through in the http headers. I have confirmed that the proper user/pass combo is passed from the proxy to Nextcloud (i.e., “Authorization: Basic secretstuffhere”), but the nextcloud logs complain,

“Sabre\DAV\Exception\NotAuthenticated”,“Message”:“No ‘Authorization: Basic’ header found. Either the client didn’t send one, or the server is misconfigured, No ‘Authorization: Bearer’ header found. Either the c
lient didn’t send one, or the server is mis-configured”…

So, either Apache2 isn’t properly forwarding this header to Nextcloud, or Nextcloud is ignoring it.


I had a similar or the same problem when I was experimenting with Apache2+php-fpm in containers. I could fix it using this rewrite rule:

Thanks for this - it appears that I’m following down a similar path. Unfortunately, it appears to me (and I’ll readily admit that I am not well versed in either Apache or PHP) that such rewrites and workarounds are already configured in .htaccess.

I turned on trace8 debugging in Apache, and I can confirm that Apache is getting the “Authorization” header, but it appears that mod_proxy_fcgi is passing it onwards to PHP as an environment variable.