Setting up Central behind a proxy (This authentication method is only available over HTTPS)

1. What is the issue? Please be detailed.
I have been setting up the ODK instance behind a proxy to allow other application to co-exist inside the same server. Now, ODK is working, but the upstream settings has been failing me today.
I cant get to even login though the ODK interface is loading when requested from the browser.

2. What steps can we take to reproduce this issue?
To reproduce this: You might need to have:

  • Nginx (Docker container)
  • Latest Central
  • Certbot (For SSL)

3. What have you tried to fix the issue?
I tweaked all the headers as much as I could:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    
    server_name central.digitalncod.org  www.central.digitalncod.org;

    
    ssl_certificate /etc/letsencrypt/live/central.digitalncod.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/central.digitalncod.org/privkey.pem;


    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;    

    client_max_body_size 100M;

    set $central "central-nginx-1";

    location / {
        resolver 127.0.0.11 valid=30s;
        proxy_pass http://$central:80;

	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 "https";
    	proxy_set_header x-forwarded-port "444";
	
        client_max_body_size 100M;
        proxy_request_buffering off;
        proxy_buffering off;
    
	#proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
   }

}

After reviewing the code I found that somewhere somehow x-forwarded-proto header is being updated:

And the logs showed:

I tried port 444 when forwarding and it went through.

So ODK returns:
{"message": "This authentication method is only available over HTTPS","code": 401.3}

What should I do to resolve this, since currrently, all I can do is to comment that out and it works fine. But that’s not sustainable in the long run.

1 Like

This is happening to me too after I upgraded to v2025.4.0 from v2025.3.1

I configured my ODK instance using this guide https://blog.thirdculturesoftware.com/self-hosting-odk-central-under-your-college-dorm-bed/. This was working fine until I upgraded.

I’m getting this error too in central-nginx container

2025/12/20 22:25:08 [error] 18#18: *128 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 192.168.16.1, server: myodkurl.com, request: "POST /csp-report HTTP/1.1", upstream: "https://myodkip:443/api/1298632/security/?sentry_key=keyhere1234", host: "myodkurl.com" 

Hi @Jonas_George @jking ,

I wrote that guide; I'm glad it is finding use!

Like you both, I recently ran into this issue as well. Here is my post about it: ODK Central 2025.3 cannot login due to 401 DELETE /users/session/current .

You could try adding the x-forwarded-proto: 'https' header to your reverse proxies and see if that solves the issue. ODK recently changed its authentication ruleset and now requires HTTPS, which interferes with reverse proxies that do not have this header.

If that doesn’t work (for some reason), the nuclear option is to just comment out the new code found in lib/http/preprocessors:

If you comment out lines 102 and 103 above, this will give you back access to the server over HTTP in my testing.

Best of luck!

2 Likes

Hello! Thank you for that guide, it was a life saver for me :smiley: .

I added the corresponding header in nginx proxy_set_header X-Forwarded-Proto https, but it didn’t work. The rest of the configuration file is almost the same as in the guide, except for lines added by Certbot when I configured the SSL certificates.

I actually added these three lines

    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_set_header X-Forwarded-Port 443;

But that didn’t work.

In the post you shared, you said that the problem arose when you updated from v2025.2 to v2025.3. In my case, the problem started when I updated from v2025.3.1 to v2025.4.0, so maybe those are different issues.

For now I just wiped my entire ODK instance and installed v2025.3.1 again, because for now I’m just testing, so wiping everything out is not a problem.

I will try to comment those lines of code you mention when I update again. Thank you!

PS: I changed the configuration of nginx in my VPS, maybe I need to change a configuration in central-nginx?

1 Like

Hello. Thanks for this and your guide.
I did all that as well and nothing seemed to work. As of now I have just commented out the problematic code and the ODK is functioning, though it is not something that I should’ve done.

So, I am still inclined towards a much more sustainable solution.

2 Likes

@Jonas_George your issue started with an update too?

No, It was a fresh install. Though the same setup worked when I installed previous version (can't remember version number).

This one failed completely until the code was commented out.

1 Like

@Jonas_George I agree; it would be nice to have a maintainable solution for those hosting behind proxies!

When/if I get more of an opportunity to dig into the application logic, I’ll see if I can debug why the httpsOnly() call is being applied when x-forwarded-for is being properly set. It’s a strange one.

1 Like

Hi all,

I got the same problem. I updated from v2025.3.1 as I try to keep my ODK up-to-date all the time. I’m using nginx as a reverse proxy.

I solved the problem by using @jniles nuclear option and comment out those two lines, and rebuild the solution.

I also, just for curiosity I added some logging into the context.protocol and the context.headers['x-forwarded-proto'] and this are the values:
service-1 | Protocol: undefined
service-1 | Headers forwarded: http

I edited my NGINX proxy multiple times, adding different headers, but in the end was always “undefined” and “http”. This is my current setup of my reverse proxy.

location / {
proxy_pass http://localhost:8081;

proxy_redirect off;
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 https;
proxy_set_header X-Forwarded-Scheme https;
proxy_set_header X-Forwarded-Host $host;
}

Hope this help to find the problem!

Cheers,

Antonio

2 Likes

Hello @jniles . This working for me too. thank you

1 Like