WebSocket Error

Hello,

I installed VaultWarden with docker on Ubuntu 24.02, but when connecting, 2FA did not come up, so when I checked the diagnostic, I saw that it gave WebSocket error. I don’t know how to solve this, can you help me?

Installation Document: How to set up Vaultwarden

Diagnostic Content:

### Your environment (Generated via diagnostics page)

* Vaultwarden version: v1.34.1
* Web-vault version: v2025.5.0
* OS/Arch: linux/x86_64
* Running within a container: true (Base: Debian)
* Database type: SQLite
* Database version: 3.49.1
* Uses config.json: true
* Uses a reverse proxy: true
* IP Header check: true (X-Real-IP)
* Internet access: true
* Internet access via a proxy: false
* DNS Check: true
* TZ environment: Europe/Istanbul
* Browser/Server Time Check: true
* Server/NTP Time Check: true
* Domain Configuration Check: true
* HTTPS Check: true
* Websocket Check: false
* HTTP Response Checks: false

### Config & Details (Generated via diagnostics page)

<details><summary>Show Config & Details</summary>

**Environment settings which are overridden:** SENDS_ALLOWED, SIGNUPS_ALLOWED, SIGNUPS_VERIFY, PASSWORD_ITERATIONS, ADMIN_TOKEN

**Failed HTTP Checks:**

```yaml
HTTP error responses:
Response to: 404 (Not Found) HTML is invalid
Response to: 404 (Not Found) JSON is invalid
Response to: 400 (Bad Request) is invalid
Response to: 401 (Unauthorized) is invalid
Response to: 403 (Forbidden) is invalid

Config:

{
  "_duo_akey": null,
  "_enable_duo": true,
  "_enable_email_2fa": true,
  "_enable_smtp": true,
  "_enable_yubico": true,
  "_icon_service_csp": "",
  "_icon_service_url": "",
  "_ip_header_enabled": true,
  "_max_note_size": 10000,
  "_smtp_img_src": "***:",
  "admin_ratelimit_max_burst": 3,
  "admin_ratelimit_seconds": 300,
  "admin_session_lifetime": 20,
  "admin_token": "***",
  "allowed_connect_src": "",
  "allowed_iframe_ancestors": "",
  "attachments_folder": "data/attachments",
  "auth_request_purge_schedule": "30 * * * * *",
  "authenticator_disable_time_drift": false,
  "data_folder": "data",
  "database_conn_init": "",
  "database_max_conns": 10,
  "database_timeout": 30,
  "database_url": "***************",
  "db_connection_retries": 15,
  "disable_2fa_remember": false,
  "disable_admin_token": false,
  "disable_icon_download": false,
  "domain": "*****://*********************",
  "domain_origin": "*****://*********************",
  "domain_path": "",
  "domain_set": true,
  "duo_context_purge_schedule": "30 * * * * *",
  "duo_host": null,
  "duo_ikey": null,
  "duo_skey": null,
  "duo_use_iframe": false,
  "email_2fa_auto_fallback": false,
  "email_2fa_enforce_on_verified_invite": true,
  "email_attempts_limit": 3,
  "email_change_allowed": true,
  "email_expiration_time": 600,
  "email_token_size": 6,
  "emergency_access_allowed": true,
  "emergency_notification_reminder_schedule": "0 3 * * * *",
  "emergency_request_timeout_schedule": "0 7 * * * *",
  "enable_db_wal": true,
  "enable_websocket": true,
  "enforce_single_org_with_reset_pw_policy": false,
  "event_cleanup_schedule": "0 10 0 * * *",
  "events_days_retain": null,
  "experimental_client_feature_flags": "",
  "extended_logging": true,
  "helo_name": "*******************************",
  "hibp_api_key": null,
  "http_request_block_non_global_ips": true,
  "http_request_block_regex": null,
  "icon_blacklist_non_global_ips": true,
  "icon_blacklist_regex": null,
  "icon_cache_folder": "data/icon_cache",
  "icon_cache_negttl": 259200,
  "icon_cache_ttl": 2592000,
  "icon_download_timeout": 10,
  "icon_redirect_code": 302,
  "icon_service": "internal",
  "incomplete_2fa_schedule": "30 * * * * *",
  "incomplete_2fa_time_limit": 3,
  "increase_note_size_limit": false,
  "invitation_expiration_hours": 120,
  "invitation_org_name": "PassBolt Türkiye",
  "invitations_allowed": true,
  "ip_header": "X-Real-IP",
  "job_poll_interval_ms": 30000,
  "log_file": "/data/vaultwarden.log",
  "log_level": "warn",
  "log_timestamp_format": "%Y-%m-%d %H:%M:%S.%3f",
  "login_ratelimit_max_burst": 10,
  "login_ratelimit_seconds": 60,
  "org_attachment_limit": null,
  "org_creation_users": "",
  "org_events_enabled": false,
  "org_groups_enabled": false,
  "password_hints_allowed": true,
  "password_iterations": 500000,
  "push_enabled": false,
  "push_identity_uri": 
  "push_installation_id": "***",
  "push_installation_key": "***",
  "push_relay_uri":
  "reload_templates": false,
  "require_device_email": false,
  "rsa_key_filename": "data/rsa_key",
  "send_purge_schedule": "0 5 * * * *",
  "sendmail_command": null,
  "sends_allowed": true,
  "sends_folder": "data/sends",
  "show_password_hint": false,
  "signups_allowed": true,
  "signups_domains_whitelist": "",
  "signups_verify": true,
  "signups_verify_resend_limit": 6,
  "signups_verify_resend_time": 3600,
  "smtp_accept_invalid_certs": true,
  "smtp_accept_invalid_hostnames": true,
  "smtp_auth_mechanism": "Login",
  "smtp_debug": false,
  "smtp_embed_images": true,
  "smtp_explicit_tls": null,
  "smtp_from": "*********************",
  "smtp_from_name": "PassBolt Türkiye",
  "smtp_host": "*******************************",
  "smtp_password": "***",
  "smtp_port": 465,
  "smtp_security": "force_tls",
  "smtp_ssl": null,
  "smtp_timeout": 15,
  "smtp_username": "*********************",
  "templates_folder": "data/templates",
  "tmp_folder": "data/tmp",
  "trash_auto_delete_days": null,
  "trash_purge_schedule": "0 5 0 * * *",
  "use_sendmail": false,
  "use_syslog": false,
  "user_attachment_limit": null,
  "user_send_limit": null,
  "web_vault_enabled": true,
  "web_vault_folder": "web-vault/",
  "yubico_client_id": null,
  "yubico_secret_key": null,
  "yubico_server": null
}

docker_compose.yml content:

services:
traefik:
image: traefik:latest
container_name: traefik
command:
- --providers.docker=true
- --providers.docker.exposedByDefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.myresolver.acme.tlschallenge=true
- --certificatesresolvers.myresolver.acme.email=${LETS_ENCRYPT_MAIL}
- --certificatesresolvers.myresolver.acme.storage=acme.json
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
- --log.level=DEBUG
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /opt/docker/le:/letsencrypt

waf:
image: owasp/modsecurity-crs:apache
container_name: waf
environment:
PARANOIA: 1
ANOMALY_INBOUND: 10
ANOMALY_OUTBOUND: 5
PROXY: 1
REMOTEIP_INT_PROXY: “172.20.0.1/16”
BACKEND: “h t t p:// vaultwarden :80”
BACKEND_WS: “ws://vaultwarden:80/notifications/hub”
ERRORLOG: “/var/log/waf/waf.log”
volumes:
- /opt/docker/waf:/var/log/waf
- /opt/docker/waf-rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
- /opt/docker/waf-rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
labels:
- traefik.enable=true
- traefik.http.middlewares.redirect-https.redirectScheme.scheme=https
- traefik.http.middlewares.redirect-https.redirectScheme.permanent=true
- traefik.http.routers.vw-ui-https.rule=Host(${VAULTWARDEN_DOMAIN})
- traefik.http.routers.vw-ui-https.entrypoints=websecure
- traefik.http.routers.vw-ui-https.tls=true
- traefik.http.routers.vw-ui-https.service=vw-ui
- traefik.http.routers.vw-ui-http.rule=Host(${VAULTWARDEN_DOMAIN})
- traefik.http.routers.vw-ui-http.entrypoints=web
- traefik.http.routers.vw-ui-http.middlewares=redirect-https
- traefik.http.routers.vw-ui-http.service=vw-ui
- traefik.http.routers.vw-ui-https.tls.certresolver=myresolver
- traefik.http.services.vw-ui.loadbalancer.server.port=8080
- traefik.http.routers.vw-websocket-https.rule=Host(${VAULTWARDEN_DOMAIN}) && Path(/notifications/hub)
- traefik.http.routers.vw-websocket-https.entrypoints=websecure
- traefik.http.routers.vw-websocket-https.tls=true
- traefik.http.routers.vw-websocket-https.service=vw-websocket
- traefik.http.routers.vw-websocket-http.rule=Host(${VAULTWARDEN_DOMAIN}) && Path(/notifications/hub)
- traefik.http.routers.vw-websocket-http.entrypoints=web
- traefik.http.routers.vw-websocket-http.middlewares=redirect-https
- traefik.http.routers.vw-websocket-http.service=vw-websocket
- traefik.http.routers.vw-websocket-https.tls.certresolver=myresolver
- traefik.http.services.vw-websocket.loadbalancer.server.port=3012

vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
WEBSOCKET_ENABLED: “true”
SENDS_ALLOWED: “true”
PASSWORD_ITERATIONS: 500000
SIGNUPS_ALLOWED: “true”
SIGNUPS_VERIFY: “true”
ADMIN_TOKEN: “${ADMIN_TOKEN}”

DOMAIN: “SMTP domain host name”

SMTP_HOST: “smtp server”

SMTP_FROM: “sender email e.g: holu@example.com

SMTP_FROM_NAME: “sender name”

SMTP_SECURITY: “starttls”

SMTP_PORT: 587

SMTP_USERNAME: “smtp username”

SMTP_PASSWORD: “smtp password”

SMTP_TIMEOUT: 15

  LOG_FILE: "/data/vaultwarden.log"
  LOG_LEVEL: "warn"
  EXTENDED_LOGGING: "true"
  TZ: "${TZ}"
volumes:
  - /opt/docker/vaultwarden:/data

networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/16

You have missed the pinned topic ⚠️ [NOTE] BREAKING CHANGE in upcoming v1.31.0 stable version - #3

Thank you Now it works without any problems. @BlackDex