#安装错误
1 messages · Page 1 of 1 (latest)
That output is from the installer wrapper — the real reason is in the installer log it printed:
1) Please paste the error from the log
Run this on the same machine and paste the output here:
sudo tail -n 200 /tmp/tmp.IuTeO8lSG5
If that file is gone (tmp cleaned), rerun the installer in verbose mode (docs recommend this):
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --verbose
Docs: https://docs.openclaw.ai/help/faq#installer-stuck-how-do-i-get-more-feedback
2) Also paste basic platform info (native deps matter)
cat /etc/os-release
uname -m
ldd --version | head -n 1
3) Common cause (Linux): missing build toolchain for native modules
OpenClaw pulls native deps (e.g. sharp, sometimes sqlite bindings). If the log shows node-gyp / compile errors, install build tools, then retry:
Debian/Ubuntu:
sudo apt-get update
sudo apt-get install -y build-essential python3 pkg-config
But before guessing: the log tail will tell us exactly which dependency is failing (sharp download vs compile vs glibc/musl mismatch).
sudo tail -n 200 /tmp/tmp.IuTeO8lSG5 文件存在但是没有任何内容
如果 /tmp/tmp.IuTeO8lSG5 是空的(0 bytes),通常表示 installer 没抓到 npm 的输出——但 npm 自己一定会写详细日志(尤其你用 sudo 的话,日志在 /root 下面)。
先跑下面这几条,把输出贴出来(越原样越好):
1) 确认 installer log 真的为空
sudo ls -l /tmp/tmp.IuTeO8lSG5
sudo wc -c /tmp/tmp.IuTeO8lSG5
2) 读 npm 的真实错误日志(重点)
sudo ls -lt /root/.npm/_logs | head -n 5
# 然后把最新那个文件 tail 出来(把文件名替换成你看到的最新一条)
sudo tail -n 200 /root/.npm/_logs/<latest>.log
3) 直接手动跑一次 npm(不要 --silent,才能看到报错)
sudo env SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm install -g openclaw@latest --loglevel=verbose
4) 也请顺手贴一下系统/架构(有些发行版会导致 sharp 之类的二进制包不兼容)
cat /etc/os-release
uname -m
如果你只是想先“装上能用”,一个很实用的绕过方案是用 无 root 的本地前缀安装(官方脚本 install-cli.sh):
curl -fsSL https://openclaw.ai/install-cli.sh | bash
但先把上面 /root/.npm/_logs 的错误贴出来,我们就能精准判断到底是哪一步炸了(网络/证书/架构/编译链/权限/OOM 等)。
root @ orangepicm4 in ~ [14:58:48]
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Orange Pi 1.0.6 Focal"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
root @ orangepicm4 in ~ [14:59:01]
$ uname -m
aarch64
root @ orangepicm4 in ~ [14:59:09]
$ ldd --version | head -n 1
ldd (Ubuntu GLIBC 2.31-0ubuntu9.14) 2.31
你这个环境信息很关键:Ubuntu 20.04 / aarch64(ARM64)。在 ARM 板子上,npm install -g openclaw@latest 失败最常见的两类原因是:
- 某个原生依赖没有拿到预编译包 → 需要本机编译(node-gyp)
- 进程被系统直接杀掉(OOM / killed),所以 installer 那个
/tmp/tmp...里会是空的
现在最重要的是把 npm 的真实日志 找出来(installer 的 tmp log 为空很正常,因为它用了 --silent,而且如果被 kill 也不会有输出)。
1) 请把 npm 的日志贴出来(最关键)
sudo ls -lt /root/.npm/_logs | head -n 5
# 把最新那个文件名替换进去
sudo tail -n 200 /root/.npm/_logs/<latest>.log
2) 检查是不是 OOM 被 kill 了(ARM 小机器很常见)
free -h
df -h
dmesg -T | tail -n 80
如果 dmesg 里看到 Out of memory / Killed process ... (node) / 退出码 137,那就是内存不够。
3) 直接手动跑一次 npm(打开详细输出)
sudo env SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm install -g openclaw@latest --loglevel=verbose
把最后 50~100 行贴出来就行。
先给一个“高概率能解决”的准备动作(等你贴日志前也可以做)
ARM64 上如果日志里出现 node-gyp / gyp ERR / make: not found,先装编译工具链:
sudo apt-get update
sudo apt-get install -y build-essential python3 pkg-config
你先把 /root/.npm/_logs 最新那份日志 tail 出来,我就能告诉你到底是哪个依赖在 ARM64 上炸了(sharp / sqlite / 还是网络下载二进制被墙/超时),对应怎么修最省事。
362 http cache https://registry.npmmirror.com/@aws-sdk%2Fmiddleware-host-header 105ms (cache hit)
363 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Fmiddleware-host-header set size:611184 disposed:false
364 silly fetch manifest @aws-sdk/middleware-user-agent@^3.972.15
365 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Fmiddleware-user-agent cache-miss
366 http cache https://registry.npmmirror.com/@aws-sdk%2Fcredential-provider-node 147ms (cache hit)
367 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Fcredential-provider-node set size:1717589 disposed:false
368 silly fetch manifest @aws-sdk/region-config-resolver@^3.972.6
369 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Fregion-config-resolver cache-miss
370 http cache https://registry.npmmirror.com/@aws-sdk%2Fmiddleware-recursion-detection 129ms (cache hit)
371 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Fmiddleware-recursion-detection set size:467841 disposed:false
372 silly fetch manifest @aws-sdk/token-providers@3.999.0
373 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Ftoken-providers cache-miss
374 http cache https://registry.npmmirror.com/@aws-sdk%2Fregion-config-resolver 51ms (cache hit)
375 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Fregion-config-resolver set size:255988 disposed:false
376 silly fetch manifest @aws-sdk/types@^3.973.4
377 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Ftypes cache-miss
378 http cache https://registry.npmmirror.com/@aws-sdk%2Fmiddleware-user-agent 130ms (cache hit)
379 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Fmiddleware-user-agent set size:952957 disposed:false
380 silly fetch manifest @aws-sdk/util-endpoints@^3.996.3
381 silly packumentCache full:https://registry.npmmirror.com/@aws-sdk%2Futil-endpoints cache-mis
你贴的这段日志还没到报错行(都是在拉依赖),但我已经看到一个很可疑的点:你现在用的是 npmmirror(https://registry.npmmirror.com/...)。
在 ARM64(aarch64) 上,sharp / @img/sharp-* 这类平台包用镜像站经常会缺包/不同步/下载到坏包,然后 npm install 就会失败(installer 又带了 --silent,所以你看到的 /tmp log 可能是空的)。
先做两件事(很快能验证)
A. 把真实错误(日志底部)贴出来:
LOG="$(ls -t /root/.npm/_logs/*.log | head -1)"
echo "$LOG"
sudo tail -n 120 "$LOG"
sudo grep -nEi "npm ERR!|ERR!|error|sharp|@img|gyp|EAI|ECONN|ETIMEDOUT|EACCES|killed|ENOMEM" "$LOG" | tail -n 80
B. 直接绕开 npmmirror,用官方 registry 重装一次:
sudo env SHARP_IGNORE_GLOBAL_LIBVIPS=1 \
npm --registry https://registry.npmjs.org/ \
install -g openclaw@latest --loglevel=verbose
如果这一步成功,那基本就可以确定是 npmmirror 镜像导致的安装失败。
如果你想永久切回官方源
sudo npm config set registry https://registry.npmjs.org/
npm config get registry
你把上面 tail/grep 的输出贴出来,我就能确认到底是:
- 镜像缺
@img/sharp-linux-arm64(最常见) - 还是 OOM 被 kill / 编译失败(需要装 build-essential/python3 等)
r at createError (file:///usr/lib/node_modules/openclaw/node_modules/node-llama-cpp/dist/utils/spawnCommand.js:34:20)
5051 error at ChildProcess.<anonymous> (file:///usr/lib/node_modules/openclaw/node_modules/node-llama-cpp/dist/utils/spawnCommand.js:47:24)
5051 error at ChildProcess.emit (node:events:519:28)
5051 error at ChildProcess._handle.onexit (node:internal/child_process:293:12)
5051 error SpawnError: Command npm run -s cmake-js-llama -- compile --log-level warn --config Release --arch=arm64 --out localBuilds/linux-arm64 --runtime-version=22.22.0 --parallel=4 --CDGGML_BUILD_NUMBER=1 --CDCMAKE_CONFIGURATION_TYPES=Release --CDNLC_CURRENT_PLATFORM=linux-arm64 --CDNLC_TARGET_PLATFORM=linux-arm64 --CDNLC_VARIANT=b7836 --CDGGML_METAL=OFF --CDGGML_CCACHE=OFF --CDLLAMA_CURL=OFF --CDLLAMA_HTTPLIB=OFF --CDLLAMA_BUILD_BORINGSSL=OFF --CDLLAMA_OPENSSL=OFF exited with code 1
5051 error at createError (file:///usr/lib/node_modules/openclaw/node_modules/node-llama-cpp/dist/utils/spawnCommand.js:34:20)
5051 error at ChildProcess.<anonymous> (file:///usr/lib/node_modules/openclaw/node_modules/node-llama-cpp/dist/utils/spawnCommand.js:47:24)
5051 error at ChildProcess.emit (node:events:519:28)
5051 error at ChildProcess._handle.onexit (node:internal/child_process:293:12)
5052 silly unfinished npm timer reify 1772204751521
5053 silly unfinished npm timer reify:build 1772204943138
5054 silly unfinished npm timer build 1772204943147
5055 silly unfinished npm timer build:deps 1772204943150
5056 silly unfinished npm timer build:run:postinstall 1772204948748
5057 silly unfinished npm timer build:run:postinstall:node_modules/openclaw/node_modules/node-llama-cpp 1772204948748
5058 verbose cwd /root
5059 verbose os Linux 5.10.160-rockchip-rk356x
5060 verbose node v22.22.0
5061 verbose npm v10.9.4
5062 verbose exit 1
5063 verbose code 1
5064 error A complete log of this run can be found in: /root/.npm/_logs/2026-02-27T15_05_50_166Z-debug-0.log
日志里已经定位到失败点了:不是 sharp,而是 node-llama-cpp 在 ARM64 上跑 postinstall 编译失败(cmake-js-llama ... exited with code 1)。
这块主要用于“本地 llama.cpp 模型”。你现在在 Ubuntu 20.04 / aarch64,一般有两条路:
路线 A(推荐先通:不装 node-llama-cpp,先把 OpenClaw 装起来)
因为 node-llama-cpp 是 openclaw 的 peerDependency,你可以让 npm 忽略 peer deps,这样不会触发它的编译:
sudo npm --registry https://registry.npmjs.org/ install -g openclaw@latest --legacy-peer-deps
openclaw --version
这样安装成功后,云模型/大多数功能照常用;只是“本地 llama.cpp”相关功能先不可用。
路线 B(要本地模型:把编译环境补齐再装)
先把常见缺失的编译依赖装上(你这个报错 80% 是缺 cmake/编译链 或内存不够):
sudo apt-get update
sudo apt-get install -y build-essential python3 pkg-config cmake ninja-build
然后再重装(建议切回官方 registry,避免 npmmirror 缺平台包/脚本):
sudo npm --registry https://registry.npmjs.org/ install -g openclaw@latest --loglevel=verbose
还需要你再贴一段“真正的编译错误”
你贴的是最后的 SpawnError 包装信息,还没看到 CMake 具体为什么失败。请把这个文件的最后 200 行贴出来:
sudo tail -n 200 /root/.npm/_logs/2026-02-27T15_05_50_166Z-debug-0.log
如果里面出现 Killed / Out of memory,那就是编译时被 OOM 杀了(Orange Pi 上也很常见),需要加 swap 或降低并行编译。
$ sudo npm --registry https://registry.npmjs.org/ install -g openclaw@latest --legacy-peer-deps
openclaw --version
npm error code 128
npm error An unknown git error occurred
npm error command git --no-replace-objects ls-remote ssh://git@github.com/whiskeysockets/libsignal-node.git
npm error git@github.com: Permission denied (publickey).
npm error fatal: Could not read from remote repository.
npm error
npm error Please make sure you have the correct access rights
npm error and the repository exists.
npm error A complete log of this run can be found in: /root/.npm/_logs/2026-02-27T15_14_25_542Z-debug-0.log
zsh: command not found: openclaw
这个报错已经不是 ARM 编译问题了,而是 npm 在拉一个 GitHub 依赖时走了 SSH:
git ls-remote ssh://git@github.com/whiskeysockets/libsignal-node.git
Permission denied (publickey)
你的机器/root 用户没有配置 GitHub SSH key,所以必炸。
解决办法(推荐):让 git 把 GitHub SSH URL 自动改成 HTTPS
先执行(因为你用 sudo npm ...,所以要改 root 的 git 配置):
sudo git config --global url."https://github.com/".insteadOf "ssh://git@github.com/"
sudo git config --global url."https://github.com/".insteadOf "git@github.com:"
验证一下:
sudo git config --global --get-regexp '^url\..*\.insteadOf'
然后再装(同时继续用 --legacy-peer-deps 避免把 node-llama-cpp 这个 peer 依赖拉下来编译):
sudo npm --registry https://registry.npmjs.org/ install -g openclaw@latest --legacy-peer-deps
openclaw --version
如果再次重试出现 “目录非空/ENOTEMPTY”
npm 有时失败会留下残留目录(比如 /usr/lib/node_modules/.openclaw-*)。先列出来我看看再删(别直接盲删):
sudo ls -la /usr/lib/node_modules | grep -E 'openclaw|\.openclaw' || true
你先把 验证输出(get-regexp 那行)和 重新安装的最后 30 行贴出来;如果还有新错误,我们继续往下定位。
$ sudo npm --registry https://registry.npmjs.org/ install -g openclaw@latest --legacy-peer-deps
openclaw --version
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated npmlog@5.0.1: This package is no longer supported.
npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm warn deprecated are-we-there-yet@2.0.0: This package is no longer supported.
npm warn deprecated glob@7.2.3: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated gauge@3.0.2: This package is no longer supported.
npm warn deprecated node-domexception@1.0.0: Use your platform's native DOMException instead
npm warn deprecated tar@6.2.1: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated glob@10.5.0: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
added 560 packages in 4m
97 packages are looking for funding
run npm fund for details
2026.2.26
好了,这次已经装成功了:openclaw --version 输出 2026.2.26。
你看到的那堆 npm warn deprecated ... 只是依赖链里的旧包警告,不影响使用(先忽略即可)。
接下来建议你这样继续
- 跑一次 Doctor(会做基础检查/生成缺的配置):
openclaw doctor
- 然后跑 onboarding(推荐会顺便装 daemon):
openclaw onboard --install-daemon
你这次用的关键绕过是什么?
--legacy-peer-deps:避免安装/编译node-llama-cpp(ARM64 上容易炸)
--registry https://registry.npmjs.org/:避免镜像源缺包/奇怪行为- (之前那个 GitHub SSH 问题)如果你后续还会用
sudo npm装别的包,建议保留 git 的 “SSH→HTTPS” rewrite
如果你接下来在 openclaw onboard / 启动 gateway 时遇到新报错,直接贴 openclaw doctor 的输出(会自动脱敏)就能继续排。
OpenClaw如何允许局域网访问18789
默认情况下 Gateway 只绑在 127.0.0.1:18789,所以别的机器访问不到。要让 局域网能访问 18789,需要做三件事:改 bind、配好鉴权、放开防火墙。
1) 绑定到 LAN(让 18789 监听局域网网卡)
openclaw config set gateway.bind "lan"
2) 配置 Token 鉴权(非 loopback 绑定会强制要求鉴权)
先生成/查看 token:
openclaw doctor --generate-gateway-token
openclaw config get gateway.auth.token
(一般默认就是 token 模式;如果你想显式设置)
openclaw config set gateway.auth.mode "token"
然后重启:
openclaw gateway restart
3) 局域网机器访问
在网关机上查 LAN IP:
hostname -I
在另一台机器打开:
http://<你的LAN-IP>:18789/
第一次连控制台常见还需要 设备配对:如果 UI 显示 pairing required,在网关机上:
openclaw devices list
openclaw devices approve <requestId>
重要提醒:LAN 上用 http 可能会遇到 “device identity required”
官方文档说明:用 http://<lan-ip> 属于 non-secure context,浏览器 WebCrypto 受限,Control UI 可能会被默认策略拦下。推荐方案是 HTTPS(最省事是 Tailscale Serve):
openclaw gateway --tailscale serve
然后用 https://<magicdns>/ 访问。
文档:https://docs.openclaw.ai/web/control-ui
如果你不想上 Tailscale、又一定要纯 LAN 直连,我也可以带你走“HTTP 放行”的配置,但那是明显降级安全(文档里叫 break-glass),建议你先说下:你是只在家里内网用,还是会暴露到公网?
root@orangepicm4:~# openclaw gateway restart
🦞 OpenClaw 2026.2.26 (bc50708) — Ship fast, log faster.
Restarted systemd service: openclaw-gateway.service
Timed out after 60s waiting for gateway port 18789 to become healthy.
Gateway process is running but port 18789 is still free (startup hang/crash loop or very slow VM startup).
Service runtime: status=running, state=active, pid=43070, lastExit=0
Gateway port 18789 status: free.
Gateway restart timed out after 60s waiting for health checks.
这个信息的关键点是:systemd 里进程还在跑,但系统上 18789 端口根本没有在 listen(显示 free)。这通常只有两种情况:
- Gateway 启动早期就报错/崩溃循环(systemd 一直拉起来,但还没绑定端口)
- 你把
gateway.bind改成了lan/tailnet,但 没有配置鉴权,触发了“拒绝非 loopback 绑定”的安全保护(日志里会写清楚)
先别猜,直接把下面几条输出贴出来(能一次定位):
1) 看 OpenClaw 的汇总状态(最省事,默认会脱敏)
openclaw status --all
openclaw gateway status --deep
2) 看 systemd 日志(这里基本就有“为什么没绑定端口”的原因)
先试系统级:
sudo systemctl status openclaw-gateway.service --no-pager -l
sudo journalctl -u openclaw-gateway.service -n 200 --no-pager -o cat
如果上面没输出/说找不到 unit,再试 user 级:
sudo journalctl --user -u openclaw-gateway.service -n 200 --no-pager -o cat
3) 确认端口确实没起来
sudo ss -ltnp | grep 18789 || true
4) 顺手把这几个配置值贴出来(很可能就是这里导致拒绝绑定)
openclaw config get gateway.mode
openclaw config get gateway.bind
openclaw config get gateway.port
openclaw config get gateway.auth.mode
openclaw config get gateway.auth.token
如果日志里出现类似这句(很常见)
refusing to bind gateway ... without auth
那解决就是:先设置 token(或密码)再 bind 到 lan:
openclaw doctor --generate-gateway-token
openclaw config set gateway.auth.mode "token"
openclaw gateway restart
你把 journalctl 那 200 行贴出来,我就能给你一个“按日志对症下药”的修复步骤(不需要来回试错)。
Diagnosis (read-only)
Gateway connection details:
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /root/.openclaw/openclaw.json
Bind: lan
✓ Config: /root/.openclaw/openclaw.json
✓ Restart sentinel: none
✓ Port 18789
! Tailscale: off · unknown
error: Error: spawn tailscale ENOENT
✓ Skills: 4 eligible · 0 missing · /root/.openclaw/workspace
! Channel issues skipped (gateway unreachable)
Gateway health:
connect failed: connect ECONNREFUSED 127.0.0.1:18789
Pasteable debug report. Auth tokens redacted.
Troubleshooting: https://docs.openclaw.ai/troubleshooting
你这份 openclaw doctor 很明确:Gateway 根本没在 18789 上监听(ECONNREFUSED 127.0.0.1:18789),所以现在不是“防火墙没放行”,而是 服务没成功把端口跑起来/没绑定到 loopback。
先按这个顺序排:
1) 先确认 gateway 到底绑定在哪(以及 service 用的配置是不是同一份)
这条不需要 gateway 端口在线:
openclaw gateway status --deep
把输出贴出来(尤其是里面的 probe url / bind / auth 和 Config (cli) vs Config (service))。
2) 看 systemd 日志(99% 会写明“为什么没 bind 端口”)
sudo journalctl -u openclaw-gateway.service -n 200 --no-pager -o cat
sudo systemctl status openclaw-gateway.service --no-pager -l
3) 同时确认 18789 真的没在 listen(以及有没有只监听在 LAN IP 而不是 127.0.0.1)
sudo ss -ltnp | grep 18789 || true
ip -4 addr | grep inet
最常见原因(你刚把 gateway.bind 改成 lan 时会触发)
非 loopback 绑定必须配置鉴权,否则会“拒绝绑定”。你可以先确保 token 存在:
openclaw doctor --generate-gateway-token
openclaw config set gateway.auth.mode "token"
openclaw gateway restart
但在你这台机子上,到底是“拒绝绑定”、还是“服务用的不是 /root/.openclaw/openclaw.json”、还是别的启动错误,需要看上面第 1/2 步的输出才能一锤定音。你把 gateway status --deep + journalctl 那 200 行贴出来,我就能给出具体修复步骤。
◇
Service: systemd (enabled)
File logs: /tmp/openclaw/openclaw-2026-02-27.log
Command: /usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js gateway --port 18789
Service file: ~/.config/systemd/user/openclaw-gateway.service
Service env: OPENCLAW_GATEWAY_PORT=18789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=lan (0.0.0.0), port=18789 (service args)
Probe target: ws://127.0.0.1:18789
Dashboard: http://10.0.0.189:18789/
Probe note: bind=lan listens on 0.0.0.0 (all interfaces); probing via 127.0.0.1.
Runtime: running (pid 43401, state active, sub running, last exit 0, reason 0)
Warm-up: launch agents can take a few seconds. Try again shortly.
RPC probe: failed
RPC target: ws://127.0.0.1:18789
gateway closed (1006 abnormal closure (no close frame)): no close reason
Gateway target: ws://127.0.0.1:18789
Source: cli --url
Config: /root/.openclaw/openclaw.json
Gateway port 18789 is not listening (service appears running).
Logs: journalctl --user -u openclaw-gateway.service -n 200 --no-pager
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
你这个状态还没到“放行局域网访问”那一步:Gateway 进程在跑,但 18789 根本没有监听(Gateway port 18789 is not listening),所以 LAN/本机都连不上。
先把“为什么没监听”查出来(基本一条日志就能定位):
1) 直接贴 systemd user 服务日志(最关键)
按它提示的这条跑,然后把输出贴出来:
journalctl --user -u openclaw-gateway.service -n 200 --no-pager -o cat
同时也把文件日志尾巴贴一下(它已经告诉你路径):
tail -n 200 /tmp/openclaw/openclaw-2026-02-27.log
2) 先确认是不是最常见的“LAN 绑定但没配鉴权 / mode 没设”
openclaw config get gateway.mode
openclaw config get gateway.auth.mode
openclaw config get gateway.auth.token
gateway.mode应该是local(否则 Gateway 可能拒绝启动)。bind=lan时 必须有 token/password(安全护栏),建议用 token。
如果 token 为空,直接生成并显式设为 token 模式再重启:
openclaw doctor --generate-gateway-token
openclaw config set gateway.auth.mode "token"
openclaw gateway restart
3) 等端口起来以后,LAN 访问方式
当 ss -ltnp | grep 18789 能看到监听后:
- 在其他设备打开:
http://10.0.0.189:18789/ - UI 里填 Gateway Token
- 第一次远程浏览器通常还需要设备配对:
openclaw devices list
openclaw devices approve <requestId>
你先把 journalctl 那 200 行贴出来,我就能告诉你“端口为什么没起来”(是拒绝绑定、启动崩了、还是卡在初始化),然后给你对应的精确修复步骤。
root@orangepicm4:~# openclaw config get gateway.mode
🦞 OpenClaw 2026.2.26 (bc50708) — Your task has been queued; your dignity has been deprecated.
local
root@orangepicm4:~# openclaw config get gateway.auth.mode
🦞 OpenClaw 2026.2.26 (bc50708) — Your inbox, your infra, your rules.
token
root@orangepicm4:~# openclaw config get gateway.auth.token
🦞 OpenClaw 2026.2.26 (bc50708) — I keep secrets like a vault... unless you print them in debug logs again.
OPENCLAW_REDACTED
你现在的配置看起来是对的:gateway.mode=local、gateway.auth.mode=token、token 也存在。所以问题不是“没允许 LAN”,而是 Gateway 进程启动后没有成功 bind 18789(端口没监听)。
下一步只能靠日志定位它为什么没起来。请把下面两段输出贴出来(会比反复重启有效得多):
1) systemd user 服务日志(最关键)
journalctl --user -u openclaw-gateway.service -n 200 --no-pager -o cat
2) OpenClaw 文件日志(它自己也指到这个路径)
tail -n 200 /tmp/openclaw/openclaw-2026-02-27.log
(这两份日志通常会明确写出:是“拒绝绑定/鉴权护栏”、还是“配置解析错误”、还是某个依赖初始化崩了等。)
额外一个快速“分叉测试”(可选,但很有用)
用来判断是不是 lan 绑定本身导致的:
openclaw config set gateway.bind "loopback"
openclaw gateway restart
openclaw gateway status
- 如果 loopback 能正常监听 18789,那就说明问题集中在
bind=lan的路径上(比如安全护栏、网卡/权限相关)。 - 如果 loopback 也不监听,那就是 gateway 启动流程本身就挂了(日志里一定有原因)。
你把 journalctl + tail 的输出发出来,我就能给你一个确定的修复步骤。
journalctl --user -u openclaw-gateway.service -n 200 --no-pager -o cat是空js","filePathWithLine":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1012","method":"console.error"}},"time":"2026-02-27T16:07:14.449Z"}
{"0":"Gateway failed to start: Error: non-loopback Control UI requires gateway.controlUi.allowedOrigins (set explicit origins), or set gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true to use Host-header origin fallback mode","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"openclaw","date":"2026-02-27T16:07:47.261Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"file:///usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1012:68","fileName":"subsystem-DypCPrmP.js","fileNameWithLine":"subsystem-DypCPrmP.js:1012","fileColumn":"68","fileLine":"1012","filePath":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js","filePathWithLine":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1012","method":"console.error"}},"time":"2026-02-27T16:07:47.279Z"}
{"0":"Gateway failed to start: Error: non-loopback Control UI requires gateway.controlUi.allowedOrigins (set explicit origins), or set gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true to use Host-header origin fallback mode","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"openclaw","date":"2026-02-27T16:08:20.064Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"file:///usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1012:68","fileName":"subsystem-DypCPrmP.js","fileNameWithLine":"subsystem-DypCPrmP.js:1012","fileColumn":"68","fileLine":"1012","filePath":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js","filePathWithLine":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1012","method":"console.error"}},"time":"2026-02-27T16:08:20.082Z"}
日志已经把原因说死了:你把 gateway.bind=lan 之后,Gateway 直接拒绝启动,因为 非 loopback 的 Control UI 必须配置 gateway.controlUi.allowedOrigins(不然会有跨站风险)。
1) 先把 allowedOrigins 配上(用你要访问的 LAN 地址)
你前面状态里 Dashboard 是 http://10.0.0.189:18789/,那就执行:
openclaw config set gateway.controlUi.allowedOrigins '["http://10.0.0.189:18789"]'
openclaw gateway restart
然后确认端口起来了:
openclaw gateway status
ss -ltnp | grep 18789 || true
文档(Control UI / allowedOrigins):https://docs.openclaw.ai/web/control-ui
2) 从局域网访问
在另一台设备打开:
http://10.0.0.189:18789/
第一次连上如果提示 pairing required,在网关机上批准浏览器设备:
openclaw devices list
openclaw devices approve <requestId>
3) 如果你的 IP 会变(DHCP),有个“省事但不推荐”的选项
可以启用 Host-header fallback(安全性更差,不建议长期用):
openclaw config set gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback true
openclaw gateway restart
先按第 1 步配 allowedOrigins(最安全的正解)。你配完重启后如果还是起不来,把 tail -n 50 /tmp/openclaw/openclaw-2026-02-27.log 再贴一下。
提示我control ui requires device identity (use HTTPS or localhost secure context)
这是预期的安全保护:你现在用 局域网 http://10.0.0.189:18789 打开 Control UI,浏览器处在 non-secure context,WebCrypto 被限制,UI 生成不了“device identity”,所以 Gateway 拒绝连接并提示:
control ui requires device identity (use HTTPS or localhost secure context)
解决方案有三种(按推荐顺序):
方案 1(最推荐、最省事):SSH 隧道 → 用 localhost 打开
在你访问 UI 的那台电脑上执行(把用户/IP改成你的):
ssh -N -L 18789:127.0.0.1:18789 root@10.0.0.189
然后在浏览器打开:
http://127.0.0.1:18789/
localhost 在浏览器里算 secure context,不会触发 device identity 限制。第一次远程浏览器可能还会提示 pairing required,需要:
openclaw devices list
openclaw devices approve <requestId>
方案 2(推荐):用 HTTPS(Tailscale Serve)
你之前日志里 tailscale ENOENT,说明没装 tailscale。装好后:
openclaw gateway --tailscale serve
用 https://<magicdns>/ 访问。(详见文档: https://docs.openclaw.ai/web/control-ui )
方案 3(不推荐/危险):允许不带 device identity 的 HTTP
这是“break-glass”模式,安全性会明显下降(同一局域网内更容易被滥用)。如果你坚持要 LAN 直连 http,可以设置:
openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true
openclaw gateway restart
如果你告诉我:你是手机要直接访问,还是电脑访问?(以及是否愿意用 SSH / Tailscale)我可以帮你选最合适的方案。
我只是pc局域网使用
PC 局域网用的话,最稳、最推荐就是走 SSH 隧道,不用改任何“危险开关”,也不需要上 HTTPS/Tailscale。
推荐方案:SSH Port Forward(本机用 localhost 打开)
在你的 PC 上执行(把用户名/IP 换成你实际的):
ssh -N -L 18789:127.0.0.1:18789 root@10.0.0.189
然后在 PC 浏览器打开:
这样浏览器是 localhost secure context,不会再出现 device identity 的报错。
如果你用的是 Windows
- PowerShell / Windows Terminal 同样可以跑上面那条
ssh ...(Windows 10/11 自带 OpenSSH)
- 浏览器依然打开
http://127.0.0.1:18789/
第一次连接可能还会提示 pairing required
在 Orange Pi 上批准即可:
openclaw devices list
openclaw devices approve <requestId>
如果你不想每次都开 SSH 连接,也可以后面再考虑 Tailscale Serve(HTTPS),但就“PC 内网用”来说,SSH 隧道是最省心也最安全的。
考虑 Tailscale Serve(HTTPS)
可以,Tailscale Serve 是解决你这个 “LAN http → device identity” 问题的正解(给你 HTTPS,同时 Gateway 继续只绑 localhost,不用在局域网暴露 18789)。
你之前 doctor 里有 spawn tailscale ENOENT,说明 OrangePi 上还没装 tailscale。按下面做:
1) 在 OrangePi 上安装并登录 Tailscale
(按 Tailscale 官方方式装;最省事的是安装脚本)
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale up 会给你一个登录链接;用浏览器打开授权即可。然后确认在线:
tailscale status
2) 把 OpenClaw 改成 “loopback + tailscale serve”
你现在为了 bind=lan 设置过 gateway.controlUi.allowedOrigins,在 Serve 模式下建议回到 loopback(更安全也更省事):
openclaw config set gateway.bind "loopback"
openclaw config unset gateway.controlUi.allowedOrigins
openclaw config set gateway.tailscale.mode "serve"
openclaw gateway restart
文档: https://docs.openclaw.ai/gateway/tailscale
3) 拿到 HTTPS 访问地址
运行:
tailscale serve status
它会显示类似 https://<你的设备名>.<你的tailnet>.ts.net/ 的地址。
4) 在你的 PC 上访问
- PC 也安装 Tailscale,并加入同一个 tailnet(同样
tailscale up) - 用浏览器打开第 3 步的
https://...地址
第一次从新浏览器/新设备连 Control UI,可能会提示 pairing required,需要在 OrangePi 上批准:
openclaw devices list
openclaw devices approve <requestId>
如果你做完第 2 步后 openclaw gateway restart 还是起不来,把 tailscale serve status 和 /tmp/openclaw/openclaw-*.log 最后 50 行贴出来,我帮你对一下是哪一步没生效。
这种是公网转发吗?
不是“公网裸转发”。
Tailscale Serve(mode=serve) 的含义是:OpenClaw 仍然只监听本机 127.0.0.1:18789,然后由 Tailscale 在你的 tailnet 里提供一个 https://xxx.ts.net 的入口(HTTPS + 路由)。只有 同一个 tailnet 里已登录/被允许的设备能访问它。
更直白点:
- 走的是互联网链路(你家网络/运营商网络上跑的流量),但它是 Tailscale 的加密私网(VPN/tailnet),不是把 18789 端口暴露给全世界。
- 真正“公网可访问”的是 Tailscale Funnel(mode=funnel),这个会把服务公开到互联网(并且 OpenClaw 文档里要求 funnel 必须配 password,风险更高)。
怎么确认你没有开到公网
在 OrangePi 上跑:
tailscale serve status
tailscale funnel status
只要 funnel 是 off/disabled,你就不是公网暴露。
文档参考:
- Tailscale + OpenClaw: https://docs.openclaw.ai/gateway/tailscale
- Control UI(含 Serve/HTTP 限制解释): https://docs.openclaw.ai/web/control-ui
如果你只想“局域网 PC 用”,但又想要 HTTPS(避免 device identity 问题),Serve 是很合适的;它的暴露面主要取决于你的 tailnet 里有哪些设备、以及 Tailscale ACL 怎么配。
这样会影响速度吗?
会有一点点影响,但通常很小,对 Control UI 这种交互来说基本感觉不出来。
大概是这样:
- 直连 LAN(http://10.0.0.x:18789):走你家路由器内网,延迟最低。
- Tailscale Serve(https://xxx.ts.net):数据会先走 Tailscale 加密隧道。
- 如果两台设备在同一内网,Tailscale 通常会走 直连(UDP 打洞直连),延迟可能只多 1~几 ms。
- 如果直连失败,会走 DERP 中继,延迟会明显高一些(可能几十到上百 ms),但依然能用。
你可以在 OrangePi 和 PC 上用这两条看是否走直连/是否走 DERP:
tailscale status
tailscale ping <对方设备名>
如果 tailscale ping 显示 direct,基本就是“几乎不影响速度”;如果显示 derp,那就会慢一些(但通常还是可接受的)。
另外,Serve 带来的好处是:HTTPS + 不需要把 Gateway 暴露到局域网 0.0.0.0,安全性和稳定性更好(不会再卡在 device identity / allowedOrigins 这些问题上)。
如果你把 tailscale status / tailscale ping 的输出贴一下,我还能帮你判断你现在是不是走 DERP,以及怎么让它更容易直连。
我只是想接入飞书使用,然后局域网访问http://10.0.0.189:18789/只是管理
你这个需求其实很适合 “Gateway 不对局域网开放,只做出站连接到飞书;管理界面用 SSH / Tailscale HTTPS” 这种架构。
原因:飞书插件用的是 WebSocket 事件订阅(出站连接),不需要你把 18789 暴露在 LAN 上;而 Control UI 走纯 HTTP(http://10.0.0.189:18789/)会触发你看到的 device identity 限制。
A) 飞书接入(不需要开 LAN 端口)
按官方文档做(插件是必须的):
https://docs.openclaw.ai/channels/feishu
- 装插件:
openclaw plugins install @openclaw/feishu
- 配置飞书 channel(推荐用向导):
openclaw channels add
选择 Feishu,填 App ID / App Secret。
- 在飞书开放平台里把事件订阅设成 长连接 WebSocket,并订阅事件
im.message.receive_v1(文档里有截图说明)。
B) “只用于管理”的 Control UI:建议用 Tailscale Serve(HTTPS)
Serve 不是公网暴露(公网那个叫 Funnel)。Serve 是 tailnet 内可访问的 HTTPS:
https://docs.openclaw.ai/gateway/tailscale
1) 建议把 Gateway 绑定回 loopback(更安全,也避免一堆 allowedOrigins / device identity 问题)
openclaw config set gateway.bind "loopback"
openclaw config unset gateway.controlUi.allowedOrigins
openclaw config set gateway.tailscale.mode "serve"
openclaw gateway restart
2) OrangePi 上装并登录 tailscale
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
3) PC 上也装 tailscale、加入同一个 tailnet,然后打开:
tailscale serve status
它会给你一个 https://<name>.<tailnet>.ts.net/ 的地址,用浏览器打开就是 Control UI。
第一次可能需要设备配对:
openclaw devices list
openclaw devices approve <requestId>
小提示
如果你只是“同一台 PC 管理”,其实 SSH 隧道也很完美(不装 tailscale 也行):ssh -N -L 18789:127.0.0.1:18789 root@10.0.0.189 然后打开 http://127.0.0.1:18789/。
你更倾向于:PC 也装 Tailscale(方便随时 HTTPS 管理),还是只用 SSH 隧道(不引入新组件)?我可以按你选的方案给你最短的操作路径。
我不想在pc上装任何软件,也不想使用ssh隧道,不考虑安全的情况下,最方便额局域网访问http://10.0.0.189:18789/
可以做到“PC 不装任何东西 / 不用 SSH / 直接用 http://10.0.0.189:18789/”,但需要把 Control UI 的两道安全护栏关掉(很危险:同一局域网里任何人拿到你的 token/或利用浏览器状态,都可能获得管理员级控制能力)。
按你说的“不考虑安全、只求方便”,做这个 break-glass 配置:
1) 让 Gateway 继续 LAN 监听(你已经是 lan 也可以跳过)
openclaw config set gateway.bind "lan"
2) 解决 “allowedOrigins” 校验(最省事:启用 Host-header fallback)
openclaw config set gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback true --strict-json
3) 解决你现在卡住的 “control ui requires device identity(HTTP 不安全上下文)”
openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true --strict-json
4) 重启
openclaw gateway restart
然后在 PC 浏览器直接打开:
http://10.0.0.189:18789/
如果 UI 需要 token:在 OrangePi 本机打开 /root/.openclaw/openclaw.json,复制 gateway.auth.token 填进去(别把 token 发到群里)。
想恢复“正常更安全”的默认配置(建议之后一定改回去)
openclaw config unset gateway.controlUi.dangerouslyDisableDeviceAuth
openclaw config unset gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback
openclaw config set gateway.bind "loopback"
openclaw gateway restart
如果你做完第 1-4 步后页面还能打开但连不上,把 Control UI 里显示的错误(比如 1008 pairing required / unauthorized)贴一行出来,我再告诉你下一步该怎么处理。
$ openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true --strict-json
🦞 OpenClaw 2026.2.26 (bc50708) — iMessage green bubble energy, but for everyone.
Config overwrite: /root/.openclaw/openclaw.json (sha256 469d6b838a7e584083bbe00e339c92664c0560739bb25ddd57c9ef56341f2be7 -> 55b93acfe1a54b5a91a32a4014aba244eb166ed5a08845e0c276b118ed57746f, backup=/root/.openclaw/openclaw.json.bak)
Updated gateway.controlUi.dangerouslyDisableDeviceAuth. Restart the gateway to apply.
root @ orangepicm4 in ~ [16:38:30]
$ openclaw gateway restart
🦞 OpenClaw 2026.2.26 (bc50708) — Your messages, your servers, your control.
Restarted systemd service: openclaw-gateway.service
Timed out after 60s waiting for gateway port 18789 to become healthy.
Gateway process is running but port 18789 is still free (startup hang/crash loop or very slow VM startup).
Service runtime: status=running, state=active, pid=45941, lastExit=0
Gateway port 18789 status: free.
Gateway restart timed out after 60s waiting for health checks.
你现在只关掉了 device identity 这一关(dangerouslyDisableDeviceAuth),但 Gateway 之所以“进程在跑、端口不监听”,通常是因为它仍然在启动阶段 直接报错退出/崩溃循环(之前你就遇到过 allowedOrigins 那个硬性校验)。
先用最省事的办法把“LAN 直连 http”需要的两个开关都打开(不安全,但你说不考虑安全):
openclaw config set gateway.bind "lan"
openclaw config set gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback true --strict-json
openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true --strict-json
openclaw gateway restart
然后立刻确认端口有没有起来:
ss -ltnp | grep 18789 || true
tail -n 80 /tmp/openclaw/openclaw-2026-02-27.log
如果还是 port 18789 is free,把 tail -n 80 /tmp/openclaw/openclaw-2026-02-27.log 的输出贴出来——里面会有“Gateway failed to start: …”的真正原因。
另外:端口起来后你用 http://10.0.0.189:18789/ 打开,第一次可能会提示 pairing required,需要在 OrangePi 上批准浏览器设备:
openclaw devices list
openclaw devices approve <requestId>
{"0":"Gateway restart timed out after 60s waiting for health checks.","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"openclaw","date":"2026-02-27T16:50:23.803Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"file:///usr/lib/node_modules/openclaw/dist/entry.js:2208:68","fileName":"entry.js","fileNameWithLine":"entry.js:2208","fileColumn":"68","fileLine":"2208","filePath":"/usr/lib/node_modules/openclaw/dist/entry.js","filePathWithLine":"/usr/lib/node_modules/openclaw/dist/entry.js:2208","method":"console.error"}},"time":"2026-02-27T16:50:23.807Z"}
{"0":"Gateway failed to start: Error: tailscale serve/funnel requires gateway bind=loopback (127.0.0.1)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"openclaw","date":"2026-02-27T16:50:31.022Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"file:///usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1012:68","fileName":"subsystem-DypCPrmP.js","fileNameWithLine":"subsystem-DypCPrmP.js:1012","fileColumn":"68","fileLine":"1012","filePath":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js","filePathWithLine":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1012","method":"console.error"}},"time":"2026-02-27T16:50:31.040Z"}
日志里这句就是原因:
tailscale serve/funnel requires gateway bind=loopback (127.0.0.1)
也就是说:你当前配置里 Tailscale Serve/Funnel 还开着,但你又把 gateway.bind 设成了 lan,两者冲突,所以 Gateway 直接拒绝启动,端口就一直是 “free”。
解决:关掉 Tailscale 模式(或者把它 unset),再重启
在 OrangePi 上执行:
openclaw config get gateway.tailscale.mode
openclaw config unset gateway.tailscale.mode
# 如果你之前写的是整个对象,也可以直接:
# openclaw config unset gateway.tailscale
openclaw gateway restart
然后确认 18789 起来了:
openclaw gateway status
ss -ltnp | grep 18789 || true
说明
- Tailscale Serve/Funnel 只能在
bind=loopback下用(它负责把 loopback 的服务通过 HTTPS 暴露出去)。 - 你现在想要 最方便的 LAN 直连
http://10.0.0.189:18789/,那就必须把 tailscale serve/funnel 关掉。
如果重启后还是没监听,再贴一下 /tmp/openclaw/openclaw-2026-02-27.log 最后 50 行,我帮你看下一条 “Gateway failed to start” 是什么。
能访问了但是提示已断开与网关的连接。
device identity required
这个提示说明:你现在用 HTTP + 非 localhost 打开 Control UI,网关还在要求 device identity(浏览器在非安全上下文下做不出来,所以就断开)。
既然你明确说“不考虑安全,只要 LAN 直连能用”,那就把 两项都开成 break‑glass(你现在可能只开了一项,或者服务没吃到配置):
在 OrangePi 上执行:
openclaw config set gateway.controlUi.allowInsecureAuth true --strict-json
openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true --strict-json
openclaw gateway restart
然后在 PC 浏览器:
- 重新加载页面(最好“强制刷新/清缓存”,因为 token/网关地址会存在 localStorage)
- 再打开
http://10.0.0.189:18789/连接
如果还是同样提示,把下面两条输出贴出来(就能确认到底是配置没生效还是别的原因):
openclaw config get gateway.controlUi.allowInsecureAuth
openclaw config get gateway.controlUi.dangerouslyDisableDeviceAuth
tail -n 80 /tmp/openclaw/openclaw-2026-02-27.log
aw-control-{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{umn":"51","fileLine":"1169","filePath":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js","filePathWithLine":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1169","method":"logToFile"}},"time":"2026-02-27T16:58:37.707Z"}
{"0":"{"subsystem":"gateway/ws"}","1":{"cause":"device-required","handshake":"failed","durationMs":26,"lastFrameType":"req","lastFrameMethod":"connect","lastFrameId":"43f8a310-a2ca-43ff-86cb-16d6985c739c","host":"10.0.0.189:18789","origin":"http://10.0.0.189:18789","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Edg/145.0.0.0","client":"openclaw-control-ui","mode":"webchat","version":"dev"},"2":"closed before connect conn=f81fac7e-9da9-48b4-bae8-58601aa536f5 remote=10.0.0.102 fwd=n/a origin=http://10.0.0.189:18789 host=10.0.0.189:18789 ua=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Edg/145.0.0.0 code=4008 reason=connect failed","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway/ws"}","parentNames":["openclaw"],"date":"2026-02-27T16:58:39.132Z","logLevelId":4,"logLevelName":"WARN","path":{"fullFilePath":"file:///usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1169:51","fileName":"subsystem-DypCPrmP.js","fileNameWithLine":"subsystem-DypCPrmP.js:1169","fileColumn":"51","fileLine":"1169","filePath":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js","filePathWithLine":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1169","method":"logToFile"}},"time":"2026-02-27T16:58:39.137Z"}
你这条日志很关键:
cause":"device-required"origin":"http://10.0.0.189:18789"
说明 Gateway 仍然在按“需要 device identity”这条规则拒绝 Control UI 的 HTTP 连接(所以你在浏览器看到断开)。
在“完全不考虑安全、只求 LAN 直连 http 能用”的前提下,把这几个开关一次性确认/补齐,然后重启:
1) 先看你现在到底开了哪些(输出会自动打码)
openclaw config get gateway.bind
openclaw config get gateway.tailscale.mode
openclaw config get gateway.controlUi.allowInsecureAuth
openclaw config get gateway.controlUi.dangerouslyDisableDeviceAuth
openclaw config get gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback
openclaw config get gateway.controlUi.allowedOrigins
2) 直接设置成“LAN 直连 http(break-glass)”组合
openclaw config unset gateway.tailscale.mode
openclaw config set gateway.bind "lan"
openclaw config set gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback true --strict-json
openclaw config set gateway.controlUi.allowInsecureAuth true --strict-json
openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true --strict-json
openclaw gateway restart
dangerouslyDisableDeviceAuth是核心;allowInsecureAuth我也建议一起开上(反正你已经走 break-glass 路线了)。
3) 浏览器端
在 PC 浏览器里对 http://10.0.0.189:18789 做一次 清站点数据/硬刷新(Chrome/Edge:锁头图标 → Site settings → Clear data),再重新打开。
接下来如果变成 1008 pairing required,那就需要在 OrangePi 上批准设备:
openclaw devices list
openclaw devices approve <requestId>
如果你做完第 2 步重启后,日志里还是 device-required,把下面两条贴出来我就能判断是“配置没被服务读到”还是“还有另一个开关在挡”:
openclaw config get gateway.controlUi
tail -n 60 /tmp/openclaw/openclaw-2026-02-27.log
{"0":"{"subsystem":"gateway/ws"}","1":{"cause":"device-required","handshake":"failed","durationMs":18,"lastFrameType":"req","lastFrameMethod":"connect","lastFrameId":"d04ecae0-b486-4f64-bc98-ed9c6be39c8d","host":"10.0.0.189:18789","origin":"http://10.0.0.189:18789","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Edg/145.0.0.0","client":"openclaw-control-ui","mode":"webchat","version":"dev"},"2":"closed before connect conn=f7d1542a-51d6-49ac-8b23-117e09f4a21b remote=10.0.0.102 fwd=n/a origin=http://10.0.0.189:18789 host=10.0.0.189:18789 ua=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Edg/145.0.0.0 code=4008 reason=connect failed","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway/ws"}","parentNames":["openclaw"],"date":"2026-02-27T17:04:34.690Z","logLevelId":4,"logLevelName":"WARN","path":{"fullFilePath":"file:///usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1169:51","fileName":"subsystem-DypCPrmP.js","fileNameWithLine":"subsystem-DypCPrmP.js:1169","fileColumn":"51","fileLine":"1169","filePath":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js","filePathWithLine":"/usr/lib/node_modules/openclaw/dist/subsystem-DypCPrmP.js:1169","method":"logToFile"}},"time":"2026-02-27T17:04:34.693Z"}
日志里的 cause:"device-required" 说明:你现在这个 HTTP(非 localhost) 的 Control UI 连接,Gateway 仍然在执行“需要 device identity”的规则,所以直接用 4008 断开。
你已经设了 dangerouslyDisableDeviceAuth=true,但还需要再打开一个开关:允许在不安全的 HTTP 上做认证(否则仍会走 device-required 这条拒绝路径)。
在 OrangePi 上执行这几条:
# 1) 确认 tailscale serve/funnel 已关(避免再冲突)
openclaw config unset gateway.tailscale.mode
# 2) 关键:允许 insecure HTTP 上的 auth
openclaw config set gateway.controlUi.allowInsecureAuth true --strict-json
# 3) 你已经设过了,但再确认一次也行
openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true --strict-json
openclaw gateway restart
然后在 PC 浏览器上:
- 对
http://10.0.0.189:18789清站点数据(否则它可能还用旧的 localStorage 状态):Edge/Chrome → 地址栏左边图标 → Site settings → Clear data - 重新打开页面,设置里填 Gateway Token 再 Connect
如果还断开,把下面两条输出贴出来我就能判断是哪一个配置没生效:
openclaw config get gateway.controlUi.allowInsecureAuth
openclaw config get gateway.controlUi.dangerouslyDisableDeviceAuth
$ openclaw config get gateway.controlUi.allowInsecureAuth
openclaw config get gateway.controlUi.dangerouslyDisableDeviceAuth
🦞 OpenClaw 2026.2.26 (bc50708) — Your task has been queued; your dignity has been deprecated.
true
🦞 OpenClaw 2026.2.26 (bc50708) — Less clicking, more shipping, fewer "where did that file go" moments.
true
你现在这条日志:
{"cause":"device-required","handshake":"failed", ...}
在 allowInsecureAuth=true + dangerouslyDisableDeviceAuth=true 都已经开启的情况下,通常只剩一种可能:Control UI 这边没有带上 token/password(shared auth 失败),所以网关没法走“跳过 device”的分支,只能继续要求 device → 就报 device-required。
你要做的是:让 Control UI 确实带上 Gateway Token
最省事、也不用你手动去文件里抄 token 的方式:
- 在 OrangePi 上运行(它会打印一个带
#token=...的链接):
openclaw dashboard
- 把它打印出来的 URL 直接在 PC 浏览器打开(注意:token 在 URL 的
#后面,不会被浏览器发到服务器,但会被 UI 存进 localStorage)。
- 如果你之前打开过 UI,建议用 无痕窗口 或者先清一下该站点数据(否则老的 localStorage 可能还没 token)。
不要把
openclaw dashboard打印出来的完整链接(含 token)贴在群里。
如果你不想用 openclaw dashboard
那就只能在 OrangePi 上本地打开配置文件复制 token(同样别发出来):
/root/.openclaw/openclaw.json里的gateway.auth.token
然后在 Control UI 的设置里粘贴 token 再连接。
你试一下 openclaw dashboard 这条路,连上后如果变成 pairing required 或 unauthorized,把 UI 上那句短错误贴出来(不要贴 token)我再告诉你下一步。
我想配置模型但是报错Model Providers
Provider map keyed by provider ID containing connection/auth settings and concrete model definitions. Use stable provider keys so references from agents and tooling remain portable across environments.
Model Providers
Unsupported schema node. Use Raw mode.
Form view can't safely edit some fields. Use Raw to avoid losing config entries.
这个不是你配置错了,是 Control UI 的“表单(Form)模式”目前编辑不了 models.providers 这种动态 map 结构,所以会提示:
Unsupported schema node. Use Raw mode.
Form view can't safely edit some fields…
解决办法就两种:用 Raw 模式编辑,或者 用 CLI/向导配置模型(更推荐)。
方案 A:不用 UI 表单,直接用 CLI 配(推荐)
大多数情况下你根本不需要改 models.providers,只要把 API Key 配好 + 选一个默认模型即可:
- 先检查模型/鉴权状态:
openclaw models status
- 选模型(用列表挑,不要手写猜):
openclaw models list
# 需要全量目录的话:
openclaw models list --all
- 设置默认模型(用你 list 里看到的那个
provider/model):
openclaw models set <provider/model>
然后重启 gateway(让 daemon 吃到新配置/新环境变量):
openclaw gateway restart
文档: https://docs.openclaw.ai/cli/models 和 https://docs.openclaw.ai/concepts/models
方案 B:一定要改 models.providers(代理/baseUrl/自建兼容服务)
那就去 Control UI 里切到 Raw 模式(原始 JSON 编辑),不要用表单模式编辑这块;或者直接在服务器上编辑 /root/.openclaw/openclaw.json。
改完一样需要:
openclaw gateway restart
文档(providers 概念):https://docs.openclaw.ai/concepts/model-providers
你打算用哪个提供商来跑模型?(比如 OpenAI / Anthropic / OpenRouter / 代理 baseUrl)
告诉我提供商名字,我就给你对应的“最短配置路径”(尽量不涉及手改大段 JSON)。另外提醒:别把 API key/token 贴到群里。
如何接入到飞书?
接入飞书要点就两件:装 Feishu 插件 + 在飞书开放平台把事件订阅改成“长连接 WebSocket”。按官方文档走最稳: https://docs.openclaw.ai/channels/feishu
下面是最短步骤(在 OrangePi 上操作):
1) 安装飞书插件
openclaw plugins install @openclaw/feishu
2) 在 OpenClaw 里添加 Feishu 渠道(会写入配置)
openclaw channels add
选择 Feishu,然后填你在飞书开放平台里拿到的:
- App ID(形如
cli_xxx) - App Secret
配完后重启:
openclaw gateway restart
openclaw logs --follow
3) 在飞书开放平台创建/配置应用
在「飞书开放平台」创建企业应用 → 打开 Bot 能力,设置机器人名称。
然后在 权限管理 里按文档“Batch import”把 scopes 一次性导入(文档里有现成 JSON)。
4) 事件订阅(关键)
在「事件订阅」里选择:
- 使用长连接接收事件(WebSocket 模式)
- 添加事件:
im.message.receive_v1
注意:要先保证 gateway 正在运行,不然长连接设置可能保存失败(文档也提醒了)。
5) 测试 + 配对(默认是 pairing)
去飞书里私聊机器人发一句话,机器人会回一个 pairing code。到 OrangePi 上批准:
openclaw pairing list feishu
openclaw pairing approve feishu <CODE>
你用的是 飞书中国版 还是 Lark 国际版?
如果是 Lark,需要在配置里加 channels.feishu.domain: "lark"(文档里有示例)。
我已经执行了openclaw pairing approve feishu HXE6YVNW为什么还是只回复OpenClaw: access not configured.
Your Feishu user id: ou_e36b19a5372a3a87ec5c8d57200bffcd
Pairing code: UXW8H47A
Ask the bot owner to approve with:
openclaw pairing approve feishu UXW8H47A
你批准的码是 HXE6YVNW,但飞书里机器人现在给你的 pairing code 是 UXW8H47A ——必须批准“当前那条消息里显示的 code”,否则它会继续提示 access not configured 并发新 code。
在 OrangePi(跑 gateway 的那台机子)上这样做:
openclaw pairing list feishu
openclaw pairing approve feishu UXW8H47A
如果你是多账号(channels.feishu.accounts.main 这种),用 --account 指定一下更稳:
openclaw pairing approve --channel feishu --account main UXW8H47A --notify
然后回飞书里再发一句话测试(不需要重启 gateway)。
如果它还在重复发 pairing code,把 openclaw pairing list feishu 的输出贴出来(不要贴任何 token/secret),我帮你看是不是批准到别的 account / 有多个待处理请求没匹配到你的 ou_...。
$ openclaw pairing list feishu
Config warnings:\n- plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may be overridden (/usr/lib/node_modules/openclaw/extensions/feishu/index.ts)
Config warnings:\n- plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may be overridden (/usr/lib/node_modules/openclaw/extensions/feishu/index.ts)
17:51:08 [plugins] plugins.allow is empty; discovered non-bundled plugins may auto-load: feishu (/root/.openclaw/extensions/feishu/index.ts). Set plugins.allow to explicit trusted ids.
Config warnings:\n- plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may be overridden (/usr/lib/node_modules/openclaw/extensions/feishu/index.ts)
17:51:25 [plugins] feishu_doc: Registered feishu_doc, feishu_app_scopes
17:51:25 [plugins] feishu_wiki: Registered feishu_wiki tool
17:51:25 [plugins] feishu_drive: Registered feishu_drive tool
17:51:25 [plugins] feishu_bitable: Registered bitable tools
🦞 OpenClaw 2026.2.26 (bc50708) — OpenAI-compatible, not OpenAI-dependent.
│
◇ Config warnings ─────────────────────────────────────────────────────────────────────────╮
│ │
│ - plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may │
│ be overridden (/usr/lib/node_modules/openclaw/extensions/feishu/index.ts) │
│ │
你现在飞书里收到的 pairing code 是 UXW8H47A,所以必须批准这个(你之前批的 HXE6YVNW 已经不是当前这次的码了;你每发一次消息,它可能又给你生成一个新码)。
先直接在 OrangePi 上执行:
openclaw pairing approve feishu UXW8H47A --notify
如果你配置了 Feishu 多账号(channels.feishu.accounts.main 这种),pairing list 默认可能没选对 account,所以会看起来“没有请求”。你可以分别试一下:
openclaw pairing list feishu --account main
openclaw pairing approve feishu --account main UXW8H47A --notify
# 或者
openclaw pairing list feishu --account default
另外你 pairing list 里刷屏的这几行:
duplicate plugin id detectedplugins.allow is empty ...
是 插件告警,不一定是 pairing 失败的原因,但会让排查很烦。为了确认当前到底加载的是哪一个 feishu 插件,麻烦再贴一下这条输出:
openclaw plugins info feishu
以及为了避免你贴不全,建议用 JSON 直接看 pending pairing(不会被 UI 框框截断):
openclaw pairing list feishu --json
你把 pairing list ... --json 输出贴出来(code 可以贴,别贴 appSecret/token),我就能一眼看出:到底是“你批错码了”、还是“accountId 不匹配”、还是“feishu 插件重复加载导致 channel 实际跑在另一个实例上”。
每一句话都要批准吗?可以自动批准吗?
不用,每一句话都批准一次是不正常的。
正常流程是:
- 第一次给某个飞书用户(
ou_...)发 pairing code - 你在网关机上
openclaw pairing approve feishu <CODE>批准一次 - 之后这个用户就一直能聊,不会每句都出码
你现在“每句话都出新码”,通常是下面几种原因之一:
1) 你其实还没批准到“正确的 code / 正确的账号”
飞书里显示什么 code,就批准什么 code(不要批准旧的)。
如果你有多账号,要加 --account main 批准到同一个 account。
2) Gateway 状态没持久化(每次都当成新会话)
比如 gateway 重启、或者插件/配置有问题导致 pairing store 没写进去。
3) 你现在加载了 重复的 feishu 插件(你日志里有 duplicate plugin id detected)
这很可疑:可能你在 ~/.openclaw/extensions/ 和安装目录里各有一份 feishu,导致行为混乱。
能不能“自动批准”?
可以把 DM 策略从 pairing 改成更宽松的策略,但这会降低安全性。
A) 最简单:直接允许所有人 DM(不需要 pairing)
openclaw config set channels.feishu.dmPolicy "open"
openclaw config set channels.feishu.allowFrom '["*"]' --strict-json
openclaw gateway restart
B) 更安全一点:只允许你自己(用你飞书返回的 user id)
你飞书里已经给了你的 ou_...,比如:
openclaw config set channels.feishu.dmPolicy "allowlist"
openclaw config set channels.feishu.allowFrom '["ou_e36b19a5372a3a87ec5c8d57200bffcd"]' --strict-json
openclaw gateway restart
文档(Feishu access control):https://docs.openclaw.ai/channels/feishu
但我建议你先把“每句都要批准”的根因修掉
请贴一下这两条输出(不包含任何 secret):
openclaw pairing list feishu --json
openclaw plugins list | grep -i feishu || true
我想确认是不是“批准没落盘/批准到错 account/插件重复加载”导致 pairing 一直不生效。
[plugins] feishu_doc: Registered feishu_doc, feishu_app_scopes
[plugins] feishu_wiki: Registered feishu_wiki tool
[plugins] feishu_drive: Registered feishu_drive tool
[plugins] feishu_bitable: Registered bitable tools
│ - plugins.entries.feishu: plugin feishu: duplicate plugin id detected; │
│ (/usr/lib/node_modules/openclaw/extensions/feishu/index.ts) │
Config warnings:\n- plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may be overridden (/usr/lib/node_modules/openclaw/extensions/feishu/index.ts)
│ Feishu │ feishu │ loaded │ global:feishu/index.ts │ 2026.2.25 │
│ │ │ │ Feishu/Lark channel plugin │ │
│ @openclaw/ │ feishu │ disabled │ stock:feishu/index.ts │ 2026.2.26 │
│ feishu │ │ │ OpenClaw Feishu/Lark channel plugin (community maintained by │ │
不用,每句话都要批准一次 = pairing 没真正生效。
从你贴的 plugins list 看,你现在实际加载的是 global 的 feishu 插件(2026.2.25),而且还有一个 bundled/stock(2026.2.26) 同 ID 的副本(所以一直有 duplicate plugin id 警告)。再加上 Feishu 可能是 多账号 accountId=main,最常见就会出现:你批准了,但批准落在“另一个 account/另一个插件实例”上,于是用户还是一直被当作未配置。
先把 pairing 一次性弄对(不需要改策略)
-
确认你的 Feishu accountId 是不是
main
在机器上看一下配置里channels.feishu.accounts的 key(不要把 appSecret 贴出来)。如果看到main,那就用--account main。 -
以后批准用这一条(用飞书消息里最新那个 code):
openclaw pairing approve --channel feishu --account main <CODE> --notify
--notify 会在飞书里回一条确认消息,能立刻验证“批准真的生效了”。
- 再检查 pending 列表(建议用 json,避免被 warning 框框吞掉输出):
openclaw pairing list --channel feishu --account main --json
把插件重复/版本不一致先修一下(强烈建议)
你现在 loaded 的是 2026.2.25,建议更新到最新版以免踩 bug:
openclaw plugins update feishu
openclaw gateway restart
(如果 plugins update 说无法更新,那就告诉我它的输出;我再给你“删掉 global 只用 stock”那条路线。)
如果你就是想“完全不需要 pairing”
可以直接改成 allowlist(只允许你这个 ou_...),以后就不会出 pairing code 了:
openclaw config set channels.feishu.dmPolicy "allowlist"
openclaw config set channels.feishu.allowFrom '["ou_e36b19a5372a3a87ec5c8d57200bffcd"]' --strict-json
openclaw gateway restart
你先告诉我:你的 channels.feishu.accounts 下面是不是 main?如果是,那你之前没带 --account main 基本就是根因。
如何删除重复的feishu
你这个“重复 feishu”是因为:你既有一份自己安装到 ~/.openclaw/extensions/feishu 的插件(global,版本 2026.2.25),又有一份 OpenClaw 自带的 bundled 插件(stock,版本 2026.2.26)。两个都叫 feishu,所以报 duplicate plugin id.
最简单的处理:删/移走你自己装的那份 global,让系统只用 stock 这份。
1) 先停掉 gateway(避免文件占用)
openclaw gateway stop
2) 把你安装的 feishu 插件目录“移走备份”(推荐,不要直接 rm)
(你是 root 在跑,所以 ~ 是 /root)
ls -la /root/.openclaw/extensions/feishu
mv /root/.openclaw/extensions/feishu /root/.openclaw/extensions/feishu.bak
3) 启用自带的 stock feishu 插件 + 重启
openclaw plugins enable feishu
openclaw gateway start
# 或者:
# openclaw gateway restart
4) 验证只剩一个 feishu
openclaw plugins list | grep -i feishu
你应该看到 stock:feishu/index.ts 是 loaded,而 global:... 不再出现,重复警告也会消失。
如果你不想用自带 stock,而是坚持用你安装的那份(global),那就没法“删除” stock(它是随 OpenClaw 安装在
/usr/lib/node_modules/openclaw/extensions/里的),只能接受重复 warning;所以推荐按上面方案回到 stock。
⚠️ Agent failed before reply: No API key found for provider "anthropic". Auth store: C:\Users\i5451.openclaw\agents\main\agent\auth-profiles.json (agentDir: C:\Users\i5451.openclaw\agents\main\agent). Configure auth for this agent (openclaw agents add <id>) or copy auth-profiles.json from the main agentDir.
Logs: openclaw logs --follow
这个报错的意思很直接:当前会话想用 anthropic 这个模型提供商,但你的 Gateway 所在机器上 没有配置 Anthropic 的凭证,所以 agent 直接在“回复之前”就失败了。
先确认一点:你现在 Gateway 跑在哪台机器?
- 报错里出现了
C:\Users\i5451\.openclaw\...,这看起来是 Windows。 - 如果你的 Gateway 实际跑在 OrangePi/Linux 上,那就必须在 OrangePi 那台机子配置 key(而不是 PC)。
方案 1(推荐):给 Anthropic 配 API Key,然后重启 Gateway
Windows(PowerShell):
- 把 key 写进
.openclaw\.env(不要发到群里)
notepad $env:USERPROFILE\.openclaw\.env
加一行:
ANTHROPIC_API_KEY=你的key
- 重启:
openclaw gateway restart
openclaw models status
Linux/OrangePi(如果 Gateway 在这里跑):
nano /root/.openclaw/.env
# 添加:ANTHROPIC_API_KEY=你的key
openclaw gateway restart
openclaw models status
文档也提到:daemon 场景最好放 ~/.openclaw/.env,否则环境变量可能进不了服务进程。