Socket.IO over HTTPS on Frappe/ERPNext 16: Unauthorized via Nginx proxy

Hi all,

I’m running into an issue with ERPNext v16 behind Nginx with HTTPS and Socket.IO.

Setup:

  • Site: frontend

  • HTTPS domain: https://frontend.example.com

  • ERPNext HTTP: http://example.com:8080

  • Direct HTTP access to ERPNext works fine

  • Via Nginx + HTTPS, the browser always shows:

Error connecting to socket.io: Unauthorized: TypeError: fetch failed

Nginx socket.io location:

location /socket.io/ {
    proxy_pass http://example.com:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 3600;
}

Problem summary:

  • Socket.IO works correctly on the direct HTTP URL (http://example.com:8080) :white_check_mark:

  • Through HTTPS + Nginx proxy (https://frontend.example.com) it fails with Unauthorized :cross_mark:

Additional info:

  • I’ve noticed that on Frappe Cloud this problem doesn’t happen

  • I understand that Frappe Cloud uses Traefik for proxying WebSockets

Questions:

  • Has anyone successfully run ERPNext v16 with Socket.IO via Nginx + HTTPS?

  • What additional settings are required for proper WebSocket authentication over HTTPS?

Any advice or working configuration examples would be greatly appreciated.

1 Like

Hi!

Part of my nginx config:

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Frappe-Site-Name $host;

        location /socket.io {
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header X-Frappe-Site-Name $host;
                proxy_set_header Origin $scheme://$http_host;
                proxy_set_header Host $host;
                proxy_pass http://erp_host:80;
        }

Sockets work fine.

If all fails try this easy install script for v16 production (with Traefik SSL): -

I added X-Frappe-Site-Name and Origin headers to my Nginx Socket io proxy configuration, but the issue still persists. I’m still getting the same Unauthorized Socket io error when using HTTPS through the proxy.

I also tried deploying ERPNext v16 using the official easy-install production script with Traefik and SSL, but I’m still getting a socketio error:

Error connecting to socket.io: Unauthorized: SyntaxError: Unexpected non-whitespace character after JSON at position 4 (line 1 column 5)

Deployment command I used (in case it helps):

export SITES_RULE='Host(`example.com`)'
python3 easy-install.py deploy --version=version-16 --email=user@example.com --sitename=example.com --app=erpnext

So even with the default Traefik setup, the issue persists.

I also tested ERPNext v15 and I’m seeing a Socket.IO error there:

Firefox can’t establish a connection to the server at 
wss://example.com/socket.io/?EIO=4&transport=websocket...

Error connecting to socket.io: Unauthorized: Error: Not Found

Deployment command I used:

python3 easy-install.py deploy --version=version-15 --email=user@example.com --sitename=example.com --app=erpnext

I’ve tried your config and it works on my side. Looks like problem not in this part.

When using the official easy-install script (Traefik + SSL), ERPNext v16 works fine HTTP, HTTPS, and socket io connections work perfectly when connecting directly to ERPNext.

However, when replacing Traefik with Nginx HTTPS connections break, socketio fails with Unauthorized or SyntaxError: Unexpected non-whitespace character after JSON
Adding all headers (X-Frappe-Site-Name, Origin, Upgrade, Connection) does not help

So the issue happens only when connecting through Nginx proxy — direct connections to ERPNext remain fully functional.

That’s interesting)

You can send me DM your full config and I’ll check it and try on my server

@Ibragim_Ganizade

by the way the left diagram also has nginx in it
Client → Traefik (for automated SSL purposes) → Nginx → Gunicorn

It seems you really want to use nginx instead of Traefik for SSL so if you know some deeper docker concepts then check out - frappe_docker/docs/02-setup/08-single-server-nginxproxy-example.md at main · frappe/frappe_docker · GitHub

If you want to figure out your probelm maybe this can help Configuring HTTPS servers

I am having the same issue with a fresh install of bench with the default setup steps.

The connection to socketio succeeds and I receive this error and socketio closes connection

44/erp.example.com,{“message”:“Unauthorized: TypeError: fetch failed”}

I do not think this is related to nginx. After looking at the socketio middleware, the authenticate function fails because it cannot call the get_user_info function here frappe/realtime/middlewares/authenticate.js at 1307ae33eb8d9077d835382a056b26ee59550655 · frappe/frappe · GitHub

I am not sure what part of the install is done incorrectly here.

Thanks!

Yes, I also noticed that commit yesterday and already analyzed it:
https://github.com/frappe/frappe_docker/commit/99d9a1dc385d8a0660a67b0cbbfeac3d5229e58c

I’m currently actively testing it. I’ll share the results once testing is finished.

After numerous attempts, it became clear what the issue was: port 80 was closed, which caused Socket.IO errors and broke WebSocket connections in ERPNext.

It turns out that Frappe Cloud also keeps port 80 open. I had it closed for security reasons, but without it, the frontend and WebSockets don’t work properly.

Do you leave port 80 open on your servers for WebSocket/HTTP traffic?
How safe and proper is it to do so?
Why doesn’t Socket.IO work when only port 443 is open?

Thanks to everyone who helped along the way!