Soju IRC bouncer: WebSocket protocol violation: Connection header "" does not contain Upgrade

1. The problem I’m having:

I’m trying out soju IRC bouncer with gamja web UI. I’m running soju with

soju -listen ws+insecure://

which succeeds, but navigating to the subdomain I get

WebSocket protocol violation: Connection header "" does not contain Upgrade

I thought I don’t need to add any headers.

soju uses the websocket library for Go.

3. Caddy version:


4. How I installed and ran Caddy:

a. System environment:

Arch Linux

c. Service/unit/compose file:


ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile


d. My complete Caddy config: {
    encode gzip
    root * /var/www/irc

gamja docs propose an nginx config:

location / {
	root /path/to/gamja;

location /socket {
	proxy_read_timeout 600s;
	proxy_http_version 1.1;
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "Upgrade";
	proxy_set_header X-Forwarded-For $remote_addr;
	proxy_set_header X-Forwarded-Proto $scheme;

5. Links to relevant resources:

This doesn’t make sense. The reverse_proxy directive will always take precedence, so file_server will never run. This is because directives are sorted according to this directive order.

Enable the debug global option and show your logs, as instructed by the help topic template.

Thanks. Forum does not allow me to post the logs, so here is a pastebin link.

That looks like an HTTP request, not a WebSocket request. You need to initiate a websocket connection with new WebSocket() with JS in the browser.

Yeah, that’s supposed to come from gamja the web client, as in its lib/client.js.

I forgot to mention that for gamja’s config.json I am using the same style for the url parameter as in the example, so like "url": "wss://",

This brings up the gamja UI: {
    encode gzip
    root * /var/www/irc
    reverse_proxy /socket

Connecting fails due to some issue that I will ask soju/gamja devs. Thanks for the pointers!

1 Like

It helps to have valid JSON, the example in gamja’s readme has comments and I forgot that JSON does not allow them.

Working minimal gamja config.json in the context of the Caddy config above:

    "server": {
        "url": "/socket"
1 Like

I wrote an article about the setup.

1 Like

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