WebSocket issue accessing HomeAssistant via Traefik

Hello gents,

Description

I'm running Proxmox (Debian) with Traefik v3.4.4 in an LXC container and Home Assistant OS (HAOS) as a virtual machine. The Traefik container is on a VLAN designated as DMZ, while Home Assistant resides on a separate VLAN labeled Internal-Services.

Accessing Home Assistant directly via its internal IP address (bypassing the reverse proxy) works perfectly. However, when I try to access it externally via a domain name (proxied through Cloudflare, e.g., https://ha.example.com) that routes through Traefik, the connection fails (after the login form (!)). I get a page displaying a countdown and the message:

Unable to connect to Home Assistant. Retrying in XX seconds...

In the browser console, I see the following error:

WebSocket connection to 'wss://ha.example.com/api/websocket' failed

Setup of Traefik and HomeAssistant:

Static configuration of Traefik
providers:
  file:
    directory: /etc/traefik/conf.d/
entryPoints:
  web:
    address: ':80'
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ':443'
    http:
      tls:
        certResolver: cloudflare
  traefik:
    address: ':8080'
serversTransport:
  insecureSkipVerify: true
certificatesResolvers:
  cloudflare:
    acme:
      email: <my-cloudflare-email>@gmail.com
      storage: /etc/traefik/ssl/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"
api:
  dashboard: true
  insecure: true
log:
  filePath: /var/log/traefik/traefik.log
  format: json
  level: ERROR
accessLog:
  filePath: /var/log/traefik/traefik-access.log
  format: json
  filters:
    statusCodes:
      - "200"
      - "400-599"
    retryAttempts: true
    minDuration: "10ms"
  bufferingSize: 0
  fields:
    headers:
      defaultMode: drop
      names:
        User-Agent: keep
Dynamic configuration of Traefik
http:
  routers:
    traefik-dashboard:
      entryPoints:
        - "websecure"
      rule: "Host(`proxy.example.com`)"
      middlewares:
        - default-headers
      service: traefik-dashboard
      priority: 1
      tls: {}
    home-assistant:
      entryPoints:
        - "websecure"
      rule: "Host(`ha.example.com`)"
      middlewares:
        - default-headers
      service: home-assistant
      priority: 10
      tls: {}
  services:
    traefik-dashboard:
      loadBalancer:
        servers:
          - url: "http://proxy.local:8080"
        passHostHeader: true
    home-assistant:
      loadBalancer:
        servers:
          - url: "http://homeassistant.local:8123"
        passHostHeader: true
  middlewares:
    default-headers:
      headers:
        customResponseHeaders:
          X-Forwarded-Proto: "https"
HomeAssistant configuration
# Loads default set of integrations. Do not remove.
default_config:

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 10.0.0.0/28 # DMZ network -- this is where reverse proxy is located

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

Additional Notes:

  1. I've observed that, on occasion, the external access works briefly - Home Assistant loads for a few seconds. But then, when I try to logout and login again - it does not work anymore.
  2. Prior to switching to Traefik, I was using Nginx Proxy Manager. Everything worked out of the box with no special configuration - just enabling the "WebSocket" toggle was enough.
  3. The proxy.example.com (traefik dashboard) works well (as well as other services that I did not include in this post)

Please let me know if there is any other information you may need in order to advice :slight_smile:

Why do you mess with the headers? Try to remove the middleware.

Thank you for your reply.

I use Cloudflare proxy in order to hide my real ip. This middleware configuration is needed in order to handle the header added by the Cloudflare when it proxies the traffic.

Anyways, removed and it did not help - the same behavior. Any other suggestions? :slight_smile: