# OpenClaw Setup — Troubleshooting & Lessons Learned
**Stand:** 2026-05-10 | **Für:** Nachfolge-KI / zukünftige Sessions
**Zweck:** Dieses Dokument fasst alle Probleme zusammen die bei der Einrichtung von OpenClaw-Instanzen auftraten, was NICHT funktioniert hat, und was die FINALE Lösung war. Ziel: kein erneutes Stochern im Nebel.
---
## TL;DR — Die funktionierende Konfiguration
**Beide OpenClaw-Instanzen (Carlo + Lulu) laufen mit:**
1. **Image-Version:** `ghcr.io/openclaw/openclaw:2026.5.6` (NICHT `:latest`, NICHT v2026.5.7)
2. **Auth-Modus:** `mode: "password"` in openclaw.json
3. **nginx:** Basic Auth davor + Authorization-Header DURCHLEITEN (NICHT clearen)
4. **Erstmaliger Login:** Doppel-Login (nginx Basic Auth + OpenClaw Passwort) → danach gespeichert
5. **Device-Pairing:** Beim ersten Connect manuelle Approval per CLI nötig
---
## Problem 1: v2026.5.7 bricht WebSocket Scope-Resolution
### Symptom
Nach `docker compose pull && docker compose up -d` Update von v2026.5.6 → v2026.5.7:
- Rote Fehlermeldung im UI: `"This connection is missing operator.read, so existing chat history cannot be loaded yet."`
- Container-Logs zeigen: `[ws] ⇄ res ✗ node.list errorCode=INVALID_REQUEST errorMessage=missing scope: operator.read`
- Tritt sekündlich auf für `node.list` Calls
### Was NICHT geholfen hat
- Browser-Cookies löschen
- Container neu starten (`docker restart`)
- Container neu erstellen (`docker compose up -d`)
- nginx-Header `X-OpenClaw-Scopes` mit allen scopes setzen
- Authorization-Header durchleiten statt clearen
- Mode wechseln auf `token` mit injiziertem Bearer-Token
- Stundenlanges Graben im Quellcode (`/app/dist/*.js`)
### Wurzelursache
v2026.5.7 hat das Scope-Handling für WebSocket-Verbindungen in `trusted-proxy` Modus geändert. Die HTTP-Header `X-OpenClaw-Scopes` werden zwar bei HTTP-Requests gelesen (`resolveTrustedHttpOperatorScopes`), aber NICHT korrekt auf die WebSocket-Session übertragen. Das `GatewayClientScopes` Context-Object bleibt leer → alle WS-Methoden die Scopes erfordern (z.B. `node.list` braucht `operator.read`) schlagen fehl.
### FUNKTIONIERENDE LÖSUNG
**Auf v2026.5.6 zurückrollen:**
```bash
docker pull ghcr.io/openclaw/openclaw:2026.5.6
sed -i 's|image: ghcr.io/openclaw/openclaw:latest|image: ghcr.io/openclaw/openclaw:2026.5.6|' /opt/struktur/openclaw-INSTANCE/docker-compose.yml
cd /opt/struktur/openclaw-INSTANCE && docker compose up -d
```
**WARNUNG:** Das Update auf v2026.5.7 NICHT durchführen bis upstream das Scope-Problem fixt. Update-Hinweis im UI ignorieren oder per X wegklicken.
---
## Problem 2: trusted-proxy Modus funktioniert nur teilweise
### Symptom
Auch auf v2026.5.6 mit `mode: "trusted-proxy"`:
- Initialer Login funktioniert
- Erste Tests zeigen UI lädt
- ABER: WebSocket-basierte Funktionen (Chat-Historie laden, Live-Chat) brechen sobald die Browser-Session keinen gespeicherten Device-Token mehr hat (z.B. nach Cookie-Cleanup)
### Wurzelursache
`trusted-proxy` Modus authentifiziert nur HTTP-Requests via Proxy-Header (`X-Forwarded-User`, `X-OpenClaw-Scopes`). WebSocket-Verbindungen brauchen zusätzlich ein im Browser gespeichertes Device-Token. Ohne diesen Token (frische Browser-Session) gibt es keine Scope-Auflösung für WS.
### Was NICHT funktionierte
- nginx-Headers `X-OpenClaw-Scopes` setzen — nur für HTTP wirksam
- `Authorization: ""` setzen — strippt sogar legitime Bearer-Tokens
- Conditional Authorization-Stripping (`if ($http_authorization !~* "^Basic ")`) — half nicht weil Browser nach Storage-Cleanup gar kein Token mehr hat
### FUNKTIONIERENDE LÖSUNG
**Auf `mode: "password"` umstellen** (siehe Problem 3 Setup).
**WICHTIG:** trusted-proxy NICHT verwenden bis das WS-Scope-Issue gefixt ist.
---
## Problem 3: Setup für `mode: "password"` mit nginx Basic Auth davor
### Symptom (initial)
`mode: "password"` mit nginx-Konfiguration aus dem trusted-proxy Setup:
- nginx Basic Auth funktioniert
- ABER: OpenClaw zeigt Connection-Dialog: `"unauthorized: gateway password missing (enter the password in Control UI settings)"`
### Wurzelursache
nginx hatte `proxy_set_header Authorization ""` das den Authorization-Header gelöscht hat. OpenClaw konnte das Bearer-Token vom Browser nicht empfangen.
### FUNKTIONIERENDE LÖSUNG
**nginx Authorization-Header NICHT mehr clearen** (also die Zeile `proxy_set_header Authorization ""` ENTFERNEN). Browser sendet dann sowohl Basic-Auth-Header als auch (nach Login) das OpenClaw-Bearer-Token. OpenClaw ignoriert den Basic-Auth-Header und nutzt sein eigenes Bearer-Token aus Cookies/localStorage.
**Erstmaliger Browser-Login** (Doppel-Login):
1. nginx Basic Auth Dialog → User + Passwort eingeben
2. OpenClaw Connection-Dialog erscheint → Passwort eingeben → "Verbinden"
3. Device Pairing Required Fehler erscheint
4. Auf dem Server: Pairing approven (siehe Problem 4)
Nach erstem Login bleibt das Device-Token im Browser gespeichert → keine erneuten Logins nötig (außer bei Cookie/Storage-Cleanup).
---
## Problem 4: Device Pairing Required nach erstem Login
### Symptom
Nach Eingabe des Passworts im OpenClaw Connection-Dialog:
- Fehler: `"device pairing required (requestId: <UUID>)"`
### Wurzelursache
OpenClaw fordert für jeden neuen Browser/Client eine Device-Pairing-Approval. Standard-Sicherheitsmechanismus.
### FUNKTIONIERENDE LÖSUNG
Auf dem Server per CLI im Container approven:
```bash
docker exec openclaw-INSTANCE node /app/openclaw.mjs devices approve <REQUEST_UUID>
```
Die UUID kommt aus der Fehlermeldung im Browser. Alternative — Pending-Liste anzeigen:
```bash
docker exec openclaw-INSTANCE node /app/openclaw.mjs devices list
```
Nach Approval im Browser auf "Verbinden" klicken — Chat öffnet sich mit voller Historie.
---
## Komplette Setup-Anleitung (Neu-Instanz aufsetzen)
### Voraussetzungen
- Docker mit `struktur-net` Netzwerk (`172.16.0.0/12`)
- nginx mit Let's Encrypt Cert für Subdomain
- htpasswd installiert (`apt install apache2-utils`)
### Schritt 1: Pfadstruktur anlegen
```bash
mkdir -p /opt/struktur/openclaw-INSTANCE/config
mkdir -p /opt/struktur/openclaw-INSTANCE/logs
chown -R 1000:1000 /opt/struktur/openclaw-INSTANCE
```
### Schritt 2: docker-compose.yml
```yaml
services:
openclaw-INSTANCE:
image: ghcr.io/openclaw/openclaw:2026.5.6
container_name: openclaw-INSTANCE
volumes:
- ./config:/home/node/.openclaw
- ./logs:/app/logs
networks:
- struktur-net
ports:
- "PORT:18789"
restart: unless-stopped
networks:
struktur-net:
external: true
```
### Schritt 3: openclaw.json (config-Ordner)
```json
{
"gateway": {
"auth": {
"mode": "password",
"password": "INSTANCE_PASSWORD"
},
"controlUi": {
"allowedOrigins": [
"https://INSTANCE.agentsolutions-mallorca.com",
"http://localhost:18789",
"http://127.0.0.1:18789"
]
}
},
"models": {
"providers": {
"openai": {
"baseUrl": "http://hermes:3000/v1",
"apiKey": "dummy",
"models": []
}
}
},
"meta": {
"lastTouchedVersion": "2026.5.6"
}
}
```
### Schritt 4: nginx-Config (`/etc/nginx/sites-available/INSTANCE`)
```nginx
server {
listen 443 ssl;
server_name INSTANCE.agentsolutions-mallorca.com;
ssl_certificate /etc/letsencrypt/live/CERT_NAME/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/CERT_NAME/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
auth_basic "INSTANCE OpenClaw";
auth_basic_user_file /etc/nginx/.htpasswd-INSTANCE;
location / {
proxy_pass http://127.0.0.1:PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header Origin "https://INSTANCE.agentsolutions-mallorca.com";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
}
}
server {
listen 80;
server_name INSTANCE.agentsolutions-mallorca.com;
return 301 https://$host$request_uri;
}
```
**KRITISCH:** KEIN `proxy_set_header Authorization ""` setzen! Browser muss seinen Bearer-Token an OpenClaw weiterleiten können.
### Schritt 5: htpasswd erstellen
```bash
htpasswd -cb /etc/nginx/.htpasswd-INSTANCE BENUTZER 'PASSWORT'
```
### Schritt 6: Aktivieren + Container starten
```bash
ln -s /etc/nginx/sites-available/INSTANCE /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
cd /opt/struktur/openclaw-INSTANCE && docker compose up -d
```
### Schritt 7: Erst-Login Browser
1. Browser öffnen: `https://INSTANCE.agentsolutions-mallorca.com`
2. nginx Basic Auth: BENUTZER / PASSWORT
3. OpenClaw Dialog: INSTANCE_PASSWORD eingeben → "Verbinden"
4. Fehler: "device pairing required (requestId: UUID)"
5. UUID kopieren, auf Server: `docker exec openclaw-INSTANCE node /app/openclaw.mjs devices approve UUID`
6. Im Browser auf "Verbinden" klicken → Chat öffnet sich
---
## Aktuelle Instanzen (Stand 2026-05-10)
### Carlo
- **URL:** `https://carlo.agentsolutions-mallorca.com`
- **Container:** `openclaw-carlo`
- **Port:** `3001`
- **Pfad:** `/opt/struktur/openclaw-carlo/`
- **nginx Basic Auth:** `carlo` / `Carlo2026!`
- **OpenClaw Passwort:** `Carlo2026!`
### Lulu (für Mari)
- **URL:** `https://lulu.agentsolutions-mallorca.com`
- **Container:** `openclaw-lulu`
- **Port:** `3002`
- **Pfad:** `/opt/struktur/openclaw-lulu/`
- **nginx Basic Auth:** `mari` / `Lulu2026!`
- **OpenClaw Passwort:** `Lulu2026!`
- **SSL-Cert:** Nutzt SAN-Cert von `carlo.agentsolutions-mallorca.com` (deckt beide Subdomains)
---
## Verbotene Aktionen (lessons learned)
1. **NICHT auf v2026.5.7 updaten** bevor das WS-Scope-Issue offiziell gefixt ist
2. **NICHT `mode: "trusted-proxy"` verwenden** mit der aktuellen Setup-Konfiguration
3. **NICHT `proxy_set_header Authorization ""`** setzen — bricht OpenClaw Auth
4. **NICHT stundenlang im Quellcode graben** wenn ein simpler Workaround (Version-Pin + password mode) das Problem löst
5. **NICHT mehrere Befehle gleichzeitig im VPS-Terminal** absetzen — Carlo gibt immer nur das Ergebnis von einem Befehl zurück
---
## Update-Pfad (zukünftig)
Wenn ein neues OpenClaw-Release erscheint:
1. **Erst in einer Test-Instanz** prüfen ob trusted-proxy + WS Scope wieder funktioniert
2. Wenn ja: Image-Tag in beiden Instanzen aktualisieren, Container neu starten
3. Wenn nein: auf der gepinnten Version bleiben, weiter beobachten
Update-Befehl pro Instanz:
```bash
sed -i 's|image: ghcr.io/openclaw/openclaw:2026.5.6|image: ghcr.io/openclaw/openclaw:NEUE_VERSION|' /opt/struktur/openclaw-INSTANCE/docker-compose.yml
cd /opt/struktur/openclaw-INSTANCE && docker compose pull && docker compose up -d
```
---
## Bekannte Restthemen (Stand 2026-05-10)
- **Update-Notification im UI** zeigt v2026.5.7 als verfügbar — kann ignoriert werden
- **DeepSeek antwortet englisch** ohne System-Prompt — Persona auf Deutsch konfigurieren noch offen
- **Datenstruktur** für persistente Projekt-Ordner (data-carlo/, data-lulu/) noch nicht angelegt
- **Backup-Strategie** für `/opt/struktur/` noch zu definieren