HTTP 400 when upgrading SocketIO websocket

I've managed to set up traefik with TLS (self signed and LetsEncrypt). When I open my app in a web browser, it loads correctly. Everying runs with docker compose, each app has their own network.

Then, I try to open a WebSocket connection via the JavaScript SocketIO library. This doesn't work and SocketIO falls back to polling.

In the Chrome Network tap, I only see the request without any response data and the status "Finished".

In the browser console, I see this error:
websocket.js:118 WebSocket connection to 'wss://localhost:8443/socket.io/?EIO=4&transport=websocket&sid=eA3mRHvH7TPUKyOBAAAE' failed:
plus a stack trace but no details.

In the access log of traefik, I get this entry:
172.21.0.1 - test [19/Jul/2025:16:53:02 +0000] "GET /socket.io/?EIO=4&transport=websocket&sid=USvaeSWIfeMdn2V7AAAC HTTP/1.1" 400 25 "-" "-" 104 "wrink@docker" "http://172.20.0.2:5000" 2ms

172.20.0.2 is the IP address of the app's docker container.

There is no error in the app's log at that time. I'm missing the milliseconds in the access log, so I'm not sure which message could relate to the one above but I don't see any errors.

The traefik DEBUG log just shows "Authentication succeeded" at that time.

Who is causing the HTTP 400? Traefik or my own web server? If traefik is the cause, what's wrong with the request?

Enable and check Traefik debug log (doc), are routers created? Enable and check Traefik access log in JSON format (doc), what’s the output during requests?

The normal HTTP requests (*.html, *.js, *.css) get through, so the routing is fine.
The access log just says that authentication succeeded and then:

172.21.0.1 - test [19/Jul/2025:16:53:02 +0000] "GET /socket.io/?EIO=4&transport=websocket&sid=USvaeSWIfeMdn2V7AAAC HTTP/1.1" 400 25 "-" "-" 104 "app@docker" "http://172.20.0.2:5000" 2ms

How can I get Traefik to dump the request and response details (headers & body)?

As already stated

Enable and check Traefik access log in JSON format (doc), what’s the output during requests?

Thanks, I somehow missed the "JSON format". Thanks to this tip and cURL, I could see that the error is generated by Flask-SocketIO.

Hints for other people who try to solve this:
When you get this error: open the dev tools of your browser. In the network tab, select the failed request and then "copy as cURL" in the context menu. Replace "wss:" with "https:" (or "ws:" with "http:") and add -vvv to the command (very verbose output).

In my case, the response contained a "Server:" header with the value "flask" which simply couldn't come from traefik. This also showed the error message in the body which

The culprit was that I didn't correctly set up CORS in SocketIO. Check the log for "XXX is not an accepted origin.". To fix this, just add the value from the log (the XXX) and pass it in the cors_allowed_origins option to the SocketIO server.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.