NginxProxyManager / NginxProxyManager/nginx-proxy-manager

allow_websocket_upgrade=1 doesn't generate WebSocket proxy headers in nginx config after container restart

Open
#5,699 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
34.2k
Forks
3.9k
Avg merge
21h 12m
Merged PRs (30d)
20

Description

Checklist

  • I have pulled jc21/nginx-proxy-manager:latest
  • I am not using someone elses docker image
  • I have searched for similar issues (both open and closed) — #5503 is related (HTTP/2) but this is a separate issue

Describe the bug

After Docker container restart/redeploy of jc21/nginx-proxy-manager:latest, NPM regenerates all proxy_host/<ID>.conf files from templates. The database has allow_websocket_upgrade=1 correctly set, but the generated nginx configuration is missing the WebSocket upgrade headers:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;

Re-saving the proxy host via the Web UI also does not fix it — the config is regenerated but the WS headers are still absent. Manually injecting the headers into the config file (then nginx -s reload) is the only reliable workaround.

To Reproduce

  1. Create a proxy host with "Websocket Support" enabled (DB confirmed: allow_websocket_upgrade=1)
  2. Verify the initial config has WS headers → WebSocket connections work
  3. Restart the NPM container: docker restart npm
  4. Check the generated config at /data/nginx/proxy_host/<ID>.conf → WS headers are gone
  5. Try re-saving via NPM Web UI → config regenerated, headers still missing
  6. Only manual injection of the three proxy_set_header lines into the config file restores functionality

Expected behavior

When allow_websocket_upgrade=1 is set in the DB, the template engine (/app/templates/proxy_host.conf) should consistently generate:

location / {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_http_version 1.1;

    include conf.d/include/proxy.conf;
}

This should survive container restarts and config regeneration.

Environment

  • Image: jc21/nginx-proxy-manager:latest (pulled July 2026)
  • OS: Debian 5.10.0-32-amd64 (kernel 5.10)
  • Docker: 29.6.1
  • Database: MariaDB 10.11 — DB confirmed allow_websocket_upgrade=1 for the proxy host

Additional context

  • Not related to HTTP/2 (see #5503) — happens on plain HTTPS proxy hosts without HTTP/2 enabled
  • The issue appears to be in the EJS template rendering pipeline where the allow_websocket_upgrade == 1 condition fails to emit WS headers during config regeneration
  • Workaround: Manual injection of headers into /data/nginx/proxy_host/<ID>.conf + nginx -s reload
  • Once injected manually, the headers persist until the next container restart

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate the source corresponding to /app/templates/proxy_host.conf and the config-regeneration entry point; inspect how allow_websocket_upgrade is passed into EJS after a restart and after Web UI saves. Reproduce with a proxy host that has Websocket Support enabled, then verify the generated file consistently contains the three WebSocket headers after regeneration.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, mariadb, nginx, typescript
Domain
devops, infrastructure
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.