Infos:
I am not a support or hosted customer. I am an open-source user running Zammad in a self-managed Docker Compose environment behind Nginx Proxy Manager.
Used Zammad version: 7.2.1 (image Package zammad · GitHub)
Used Zammad installation type: docker-compose (official zammad/zammad-docker-compose repository, using the scenarios/add-nginx-proxy-manager.yml scenario)
Operating system: Ubuntu 24.04 (host), Docker Compose, jc21/nginx-proxy-manager latest (v2.16.0)
Browser + version: Google Chrome 153.0.0.0 (Windows 10/11, 64-bit)
Expected behavior:
After updating Zammad from a previous version to 7.2.1 (and Nginx Proxy Manager to 2.16.0), the web UI should work normally over HTTPS, including:
Submitting forms (e.g. updating tickets via the “Submit”/“Update” button).
Authenticating via POST /api/v1/signin.
Establishing the WebSocket connection at wss:///ws for real-time updates.
Actual behavior:
After the update, the following issues appear in the browser console (Chrome DevTools):
POST https://sd.*./api/v1/signin returns 422 Unprocessable Content.
WebSocket connection fails:
WebSocket connection to ‘wss://sd.*./ws’ failed: WebSocket is closed before the connection is established.
WebSocket connection to ‘wss://sd.*./ws’ failed: Error during WebSocket handshake: Unexpected response code: 502
WebSocket connection to ‘wss://sd.*.:6042/’ failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
Console error: App.route dashboard:(error) | No permission for *
Console error: App.i(error) | {_core_workflow: {…}} triggered from onSubmit (submit button handler).
The submit button in the ticket view initially did not send any request (Network tab was empty on click).
These symptoms are consistent with another user’s report on the Zammad community forum for version 7.2.1 (user GIL_IT: inability to assign/update tickets, update button not working, unsaved changes warning on leaving the ticket).
Steps to reproduce the behavior:
Deploy Zammad 7.2.1 via docker-compose using the official repository and the scenarios/add-nginx-proxy-manager.yml scenario.
Put Zammad behind Nginx Proxy Manager (NPM) v2.16.0, which terminates TLS.
Configure NPM Proxy Host:
Domain: sd.*.
Scheme: .env https
Forward Hostname: zammad-nginx
Forward Port: NPM:443 → zammad:8080
Block common exploits: enabled
Cache assets: disabled
WebSocket support: initially enabled, later disabled (see below)
Open https://sd.*./ in Chrome, log in, and try to update a ticket.
Observe errors in the browser console and failed WebSocket handshake.
Additional configuration and troubleshooting already performed:
Environment / compose setup:
.env contains NGINX_SERVER_SCHEME=https.
Setting.get(‘http_type’) in the Rails console returns https.
ActionCable is configured to accept requests from https://sd.*. (confirmed via Rails runner).
Inside the zammad-nginx container, grep “X-Forwarded-Proto” /etc/nginx/sites-available/default returns three occurrences of proxy_set_header X-Forwarded-Proto https;
The zammad-nginx container exposes 8080:8080 internally; zammad-websocket listens on 6042 internally.
NPM configuration (Advanced / Custom Nginx configuration):
text
add_header Cache-Control “no-store, no-cache, must-revalidate” always;
add_header Pragma “no_cache” always;
add_header Expires “0” always;
add_header X-Content-Type-Options “nosniff” always;
add_header X-Frame-Options “SAMEORIGIN” always;
add_header Referrer-Policy “strict-origin-when-cross-origin” always;
add_header Permissions_Policy “geolocation=(), microphone=(), camera=(), payment=()” always;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_http_version 1.1;
Troubleshooting steps already tried:
Cleared browser cache and tested in Incognito mode — errors persist.
Verified X-Forwarded-Proto https inside zammad-nginx — all three occurrences are correct.
Verified http_type = https via Rails runner.
Added proxy_set_header X-Forwarded-Proto https;, X-Forwarded-Ssl on;, X-Forwarded-Port 443; in NPM Advanced — no effect on 422.
Disabled “WebSocket support” toggle in NPM Proxy Host and added proxy_http_version 1.1; — this partially fixed the submit button and webhook delivery, but the following errors remain:
POST /api/v1/signin → 422.
WebSocket to /ws → 502.
WebSocket to :6042 → connection refused.
Ran docker compose down and up -d (without -v) to recreate containers — problem persists.
Confirmed the issue is not caused by browser caching (Incognito, cleared cache, DevTools “Disable cache” enabled).
Questions:
Is this a known regression in Zammad 7.2.1 when running behind Nginx Proxy Manager?
Is there an official recommendation for the correct NPM + zammad-docker-compose configuration to avoid the 422 CSRF error and WebSocket handshake failures?
Should the zammad-websocket container be exposed to the proxy in a different way in the add-nginx-proxy-manager.yml scenario?
Are there additional environment variables or settings (e.g. RAILS_TRUSTED_PROXIES, NGINX_SERVER_SCHEME, ActionCable allowed origins) that need to be adjusted for this specific double-proxy setup?
Any guidance would be greatly appreciated.