El panel de control de OpenClaw no carga: Soluciones para puertos, WebSockets y proxy inverso

Hola solucionadores de problemas del panel de control: si estás viendo una página en blanco, conexión rechazada o errores de "no autorizado" mientras el gateway de OpenClaw definitivamente está funcionando, he estado en tu lugar.

La semana pasada resolví este problema exacto en cuatro configuraciones: desarrollo local en Mac, Docker en Ubuntu, proxy inverso nginx y una instancia expuesta de Tailscale. Cada uno tenía un modo de falla diferente, pero todos se remontaban a las mismas cinco causas raíz.

El HTML se carga. DevTools muestra fallos en el handshake de WebSocket. Los registros del gateway no dicen nada útil. No estás seguro si es autenticación, redes o corrupción de configuración.

Esto es lo que realmente falla: encabezados de actualización de WebSocket faltantes en tu proxy, NAT de Docker tratando localhost como externo, tokens de autenticación que no persisten en localStorage, o colisiones de puertos de servicios antiguos de Clawdbot/Moltbot aún en ejecución.

Esta guía repasa el flujo de diagnóstico que construí después de arreglar estos problemas repetidamente. Comienza aquí, sigue las verificaciones, y o bien lograrás que el panel funcione o sabrás exactamente qué reportar.


Confirmar la salud del servicio

Before diving into proxies and ports, verify the gateway is actually functional.

Is the Gateway Process Running?

# Check gateway status
openclaw status
# If using systemd
systemctl --user status openclaw-gateway
# Docker users
docker ps | grep openclaw-gateway

What you're looking for:

  • Status: running or active
  • Uptime: More than 30 seconds (not crash-looping)
  • No recent restarts

If it's not running or restarting constantly, stop here and fix the gateway install issues first.

Can the WebSocket Server Respond?

Test the WebSocket endpoint directly:

# Install wscat if you don't have it
npm install -g wscat
# Test connection (replace with your actual token)
wscat -c "ws://127.0.0.1:18789/?token=YOUR_TOKEN_HERE"

Possible outcomes:

  • Connected, gets challenge message → Gateway is fine, problem is browser/proxy
  • Connection refused → Port/bind issue, go to next section
  • Connected then immediately closes with 1008 → Auth problem

If wscat connects but the browser doesn't, the issue is either CORS, proxy config, or browser security policy.

Check What the Gateway Actually Heard

Look at recent logs:

# View last 50 log lines
openclaw logs --limit 50
# Docker
docker logs openclaw-gateway --tail 50
# Look for WebSocket handshake attempts
openclaw logs | grep -E 'ws\]|websocket|handshake'

Key patterns:

  • [ws] accepted → Connection succeeded
  • [ws] closed before connect ... code=1008 reason=pairing required → Auth mismatch
  • [ws] closed before connect ... code=1008 reason=unauthorized: gateway token missing → Token not reaching gateway
  • Origin http://... is not allowed → CORS issue

Port Conflicts & Bind Addresses

Problem: Gateway Binds to Wrong Interface

Symptom: Gateway runs fine via CLI, but browser can't connect to 127.0.0.1:18789.

Cause: Gateway bound to a Tailscale IP, VPN interface, or external IP instead of loopback.

This is Issue #1380 — when Tailscale is active, the gateway sometimes binds to 100.x.x.x instead of 127.0.0.1. Browser WebSocket connections to Tailscale IPs fail.

Diagnose:

# Check what interface the gateway bound to
openclaw status
# Or inspect the actual listening socket
sudo lsof -i :18789
# Look at the "NAME" column - should show 127.0.0.1:18789

Fix:

Force loopback binding in config (~/.openclaw/config.json):

{
  "gateway": {
    "bind": "loopback",
    "port": 18789
  }
}

Valid bind options:

  • loopback → 127.0.0.1 only (default, safest)
  • lan → 0.0.0.0 (all interfaces, requires auth)
  • tailnet → Tailscale IP

After changing bind, restart:

systemctl --user restart openclaw-gateway
# or
docker compose restart openclaw-gateway

Problem: Port 18789 Already in Use

Symptom: Gateway won't start, logs show EADDRINUSE.

Cause: Old Clawdbot/Moltbot gateway still running, or another service using 18789.

Diagnose:

# Find what's using the port
sudo lsof -i :18789
# Or
sudo ss -tlnp | grep 18789

Fix Option A: Stop Conflicting Service

# Stop old Clawdbot
systemctl --user stop clawdbot-gateway
# Kill the process if needed
sudo kill -9 <PID>

Fix Option B: Change OpenClaw Port

In ~/.openclaw/config.json:

{
  "gateway": {
    "port": 18790
  }
}

Update Docker compose if using containers:

ports:
  - "127.0.0.1:18790:18790"

Then access dashboard at http://127.0.0.1:18790/.

Problem: Docker NAT Breaks Localhost Detection

Symptom: Running gateway in Docker Desktop on Windows/Mac, browser shows "pairing required" even with correct token.

Cause: Docker's NAT networking makes the gateway see connections from 172.18.0.1 instead of 127.0.0.1. Gateway treats this as an external connection requiring node pairing.

Diagnose:

Check gateway logs for:

[ws] closed before connect conn=... remote=172.18.0.1 ... code=1008 reason=pairing required

If you see remote=172.18.0.1 but you're connecting from 127.0.0.1, this is the issue.

Fix:

Add trusted proxies to your config:

{
  "gateway": {
    "trustedProxies": ["172.18.0.0/16", "172.17.0.0/16"]
  }
}

Or run gateway with --bind lan and enforce token auth:

{
  "gateway": {
    "bind": "lan",
    "auth": {
      "mode": "token",
      "token": "your-secret-token"
    }
  }
}

Better fix for Windows/Mac: Run gateway natively instead of in Docker to get real localhost connections.


Reverse Proxy WebSockets Checklist

If you're exposing OpenClaw through nginx, Caddy, or another reverse proxy, WebSocket support needs explicit configuration.

nginx Configuration

The dashboard uses WebSockets for real-time communication. Standard HTTP proxying breaks this.

Minimal working config:

server {
    listen 443 ssl;
    server_name openclaw.yourdomain.com;
    # SSL certs
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    location / {
        proxy_pass http://127.0.0.1:18789;
        # Critical for WebSockets
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";     
        # Pass through client info
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        # WebSocket timeouts
        proxy_read_timeout 86400;
        proxy_send_timeout 86400;
    }
}

Common nginx mistakes:

  • Missing proxy_http_version 1.1 → WebSocket upgrade fails
  • Missing Upgrade and Connection headers → Handshake rejected
  • Default timeout (60s) → WebSocket closes after idle time

Detailed nginx reverse proxy guide: nginx WebSocket proxying

Caddy Configuration

Caddy handles WebSockets automatically, but you still need proper config:

openclaw.yourdomain.com {
    reverse_proxy 127.0.0.1:18789
}

That's it. Caddy auto-detects the WebSocket upgrade and adjusts timeouts.

If using subpath:

yourdomain.com {
    reverse_proxy /openclaw/* 127.0.0.1:18789
}

Then access via https://yourdomain.com/openclaw/.

Debugging Caddy WebSocket issues:

Enable verbose logging:

openclaw.yourdomain.com {
    log {
        output file /var/log/caddy/openclaw.log
        level DEBUG
    }
    reverse_proxy 127.0.0.1:18789
}

Check for websocket upgrade in logs. If missing, Caddy isn't detecting the upgrade request.

Apache Configuration

Less common but occasionally used:

<VirtualHost *:443>
    ServerName openclaw.yourdomain.com
    SSLEngine On
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/key.pem
    # Enable proxy modules
    # a2enmod proxy proxy_http proxy_wstunnel rewrite
    ProxyPreserveHost On
    # WebSocket tunnel
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*)  ws://127.0.0.1:18789/$1 [P,L]
    # Regular HTTP proxy
    ProxyPass / http://127.0.0.1:18789/
    ProxyPassReverse / http://127.0.0.1:18789/
</VirtualHost>

Enable required modules:

sudo a2enmod proxy proxy_http proxy_wstunnel rewrite
sudo systemctl restart apache2

CORS / HTTPS Gotchas

Mixed Content Blocking

Symptom: Dashboard loads over HTTPS but WebSocket connection fails with mixed content error.

Cause: Browser blocks ws:// (non-secure WebSocket) when page is loaded over https://.

Fix:

Use wss:// (WebSocket Secure) behind your reverse proxy.

Your nginx/Caddy terminates SSL and forwards to http://127.0.0.1:18789, but the browser needs to connect via wss://.

Example flow:

  • Browser: wss://openclaw.yourdomain.com/ → nginx with SSL
  • nginx: ws://127.0.0.1:18789/ → gateway (local, no SSL needed)

The dashboard auto-detects this if you access it via HTTPS URL.

CORS Rejections

Symptom: Browser console shows CORS policy: No 'Access-Control-Allow-Origin' header.

Cause: Accessing dashboard from a different domain than the gateway expects.

Context: As of OpenClaw's security updates, the Control UI has stricter origin validation.

Fix:

If your dashboard is at https://openclaw.example.com but gateway config doesn't know about it:

{
  "gateway": {
    "cors": {
      "origins": ["https://openclaw.example.com"]
    }
  }
}

Security note: Don't use "origins": ["*"] in production. This exposes your gateway to external access vulnerabilities.

Token Not Persisting in localStorage

Symptom: Dashboard keeps asking for token every time you reload.

Cause: Browser's localStorage API blocked or cleared.

Diagnose:

Open DevTools → Application → Local Storage → http://127.0.0.1:18789

Look for key: openclaw-gateway-token

If missing after login, check:

  • Browser in private/incognito mode (localStorage disabled)
  • Third-party cookie blocking extensions
  • Browser set to clear storage on exit

Workaround:

Use the tokenized URL every time:

openclaw dashboard

This command outputs a URL with ?token=... appended. The UI strips it after first load and saves to localStorage — but if that fails, you need the URL each time.


Logs to Collect Before Reporting

If none of the above fixes work, you're in edge case territory. Before opening a GitHub issue, collect these logs:

Gateway Logs

# Last 100 lines with timestamps
openclaw logs --limit 100 > gateway-logs.txt
# Docker
docker logs openclaw-gateway --tail 100 > gateway-logs.txt

Browser Console Logs

  1. Open DevTools (F12)
  2. Go to Console tab
  3. Reproduce the connection failure
  4. Right-click console → Save as... → browser-console.txt

WebSocket Frame Inspection

  1. DevTools → Network tab
  2. Filter: WS
  3. Click the WebSocket connection
  4. Check "Messages" tab for handshake details
  5. Screenshot the Headers tab showing request/response

Config Sanitized

# Export config (redact tokens)
cat ~/.openclaw/config.json | sed 's/"token": ".*"/"token": "REDACTED"/g' > config-sanitized.json

Network Environment

# Check firewall rules (Linux)
sudo iptables -L -n | grep 18789
# Check what's binding to the port
sudo lsof -i :18789
# Test from external host if relevant
curl -v http://your-server-ip:18789/

What Actually Breaks Dashboards

Después de depurar esto en diferentes entornos, aquí está la distribución de fallos que observé:

60% - Falta configuración de WebSocket en el proxy inverso

  • nginx sin los encabezados Upgrade/Connection
  • Configuraciones de tiempo de espera incorrectas
  • Falta proxy_http_version 1.1

20% - Docker NAT trata localhost como externo

  • Docker Desktop en Windows/Mac
  • Solucionado ejecutando el gateway de forma nativa o añadiendo trustedProxies

10% - Conflictos de puertos por antiguos Clawdbot/Moltbot

  • Se olvidó detener los servicios antiguos antes de instalar OpenClaw
  • Solucionado matando procesos antiguos o cambiando el puerto

5% - Vinculación de Tailscale en lugar de loopback

  • Gateway se vincula a 100.x.x.x cuando Tailscale está activo
  • Solucionado forzando bind: "loopback" en la configuración

5% - Desajuste de token de autenticación

  • Token en la configuración no coincide con el token en la URL
  • Solucionado ejecutando openclaw dashboard para obtener el enlace tokenizado correcto

El más común — configuración de WebSocket en el proxy inverso — también es el más fácil de pasar por alto porque la parte HTTP funciona bien. Ves el HTML, el CSS se carga, pero WebSocket falla silenciosamente.

Si estás detrás de un proxy y el panel no se conecta, esa es tu primera verificación.

En Macaron, alojamos la interfaz de usuario por ti: sin configuraciones de nginx que depurar, sin tiempos de espera de WebSocket que ajustar, sin sorpresas de NAT de Docker. ¿Cansado de resolver problemas de infraestructura antes de poder siquiera probar los flujos de trabajo? ¿Prefieres una interfaz de usuario alojada para flujos de trabajo? Crea una cuenta en Macaron.

Preguntas Frecuentes

P: El HTML del panel de control se carga pero nada funciona. ¿Por dónde empiezo? Abre DevTools → Network → pestaña WS. Si el handshake de WebSocket está fallando, casi seguro que faltan los encabezados Upgrade y Connection en la configuración de tu proxy inverso. Eso cubre el 60% de los casos. Si primero quieres descartar una mala instalación, te recomendaría verificar con la guía de instalación de OpenClaw antes de profundizar en las configuraciones de proxy.

P: ¿Por qué mi gateway muestra "emparejamiento requerido" aunque configuré correctamente el token? Revisa tus registros en busca de remote=172.18.0.1. Si estás en Docker Desktop (Windows o Mac), NAT está haciendo que el gateway piense que eres una conexión externa. Ejecuta el gateway de forma nativa o agrega trustedProxies a tu configuración — la guía de configuración de Docker tiene la configuración de red exacta para este escenario.

P: Gateway sigue pidiendo mi token cada vez que recargo la página. El localStorage de tu navegador no se está manteniendo. Normalmente, es debido al modo incógnito, una extensión de privacidad agresiva o porque está habilitada la opción de "borrar almacenamiento al salir". Utiliza la URL tokenizada desde openclaw dashboard como solución alternativa. Si los problemas de autenticación van más allá de esto, el listado de seguridad de OpenClaw cubre la gestión de tokens con más detalle.

P: El puerto 18789 ya está en uso. ¿Qué lo está ocupando? Nueve de cada diez veces es un gateway antiguo de Moltbot o Clawdbot que sigue ejecutándose. lsof -i :18789 te dirá qué es. Mátalo o simplemente cambia el puerto de OpenClaw en la configuración. Si migraste recientemente desde Moltbot, este artículo sobre cómo ejecutar ambos juntos vale la pena leerlo — los conflictos de servicio son un problema común allí.

P: Mi tablero HTTPS no puede conectarse al WebSocket. Contenido mixto — el navegador no permitirá ws:// en una página HTTPS, punto. Tu proxy necesita manejar la terminación de wss://. Si estás en un VPS y sigues encontrando este problema, la guía de despliegue en VPS tiene una configuración de nginx + SSL que puedes usar directamente.

P: Tailscale está activo y ahora el panel no se carga localmente. Problema conocido (#1380) — Tailscale puede cambiar la puerta de enlace a 100.x.x.x en lugar de 127.0.0.1. Añade "bind": "loopback" a tu configuración y reinicia. Si el comportamiento de bind sigue siendo confuso después de eso, la referencia de puerta de enlace desglosa todas las opciones claramente.

Hola, soy Hanks — un apasionado de los flujos de trabajo y fanático de las herramientas de IA con más de diez años de experiencia práctica en automatización, SaaS y creación de contenido. Paso mis días probando herramientas para que tú no tengas que hacerlo, desglosando procesos complejos en pasos simples y accionables, y analizando los números detrás de “lo que realmente funciona.”

Aplicar para convertirse Los primeros amigos de Macaron