cloud-sre

Lighthouse 报 InvalidToken,但 Erigon 实际返回 Forbidden

一次 Gnosis Erigon 和 Lighthouse Engine API 连接问题的处理记录:看起来像 JWT 错误,实际卡在 authrpc vhost。

Jun 24, 2026
GnosisErigonLighthousearchive-nodeDocker

一台 Gnosis 归档节点使用 Erigon 做 execution layer,Lighthouse 做 consensus layer。Erigon 日志一直刷:

flag --externalcl was provided, but no CL requests to engine-api in 22h...

Lighthouse 容器也在跑,但日志反复出现:

Failed jwt authorization error: InvalidToken
Execution engine call failed error: Auth(InvalidToken)
HTTP status client error (403 Forbidden) for url (http://gnosis:8551/)

第一眼很像 JWT secret 不一致。实际不是。最后真正需要补的是 Erigon Engine API 的 vhost:

--authrpc.vhosts=gnosis,localhost,127.0.0.1

文中用语说明

用语含义
Execution layer执行区块、保存执行层数据的客户端。这里是 Erigon。
Consensus layer跟随 PoS 共识链、驱动 fork choice 的 beacon client。这里是 Lighthouse。
Engine API共识客户端和执行客户端之间的认证 API,常见端口是 8551
JWT secret共识客户端访问 Engine API 时使用的共享密钥文件。
authrpc vhostErigon 对认证 RPC 请求的 Host allowlist。JWT 正确,不代表 Host 一定被允许。
Checkpoint syncLighthouse 从最近 finalized checkpoint 启动的同步方式,比从 genesis 追 beacon chain 快很多。

日志先指向了哪里

Erigon 是用外部 consensus layer 模式启动的:

--externalcl
--authrpc.addr=0.0.0.0
--authrpc.port=8551
--authrpc.jwtsecret=/jwt/jwt.hex

这个方向本身没问题。Erigon README 里说明,Gnosis 需要在 Erigon 旁边跑一个 consensus layer client;如果 consensus client 不在本机 localhost 访问,还需要配置 --authrpc.addr 0.0.0.0--authrpc.vhosts <CL host> [1]

Lighthouse 访问的是 Docker service name:

--execution-endpoint http://gnosis:8551
--execution-jwt /jwt/jwt.hex

所以这不是单纯“带 JWT 的请求”。它还是一个 Host 为 gnosis:8551 的 HTTP 请求。

先排除 JWT

最直观的可能性是密钥不一致,所以先检查共享文件:

sha256sum /data/jwt/jwt.hex
docker exec gnosis sha256sum /jwt/jwt.hex
docker exec gnosis-lighthouse sha256sum /jwt/jwt.hex

宿主机文件、Erigon 容器挂载、Lighthouse 容器挂载都一致。

我又用同一个文件生成临时 JWT,直接调用 Erigon 的 engine_exchangeCapabilities。请求返回 HTTP 200。这个检查把范围缩小了:Erigon 能验证这个 token,Engine API 也能访问。Lighthouse 里看到的 InvalidToken,背后其实还有一层 HTTP 403。

更新 Lighthouse 时暴露出的两个小问题

当时运行的 Lighthouse 镜像比较旧,所以改成固定版本,而不是继续依赖 floating tag:

sigp/lighthouse:v8.2.0

Lighthouse v8.2.0 当时是当前 release,官方标记为 high-priority [2]

升级后先遇到旧数据库打不开:

Unable to open database: LoadConfig(ConfigError(InvalidVersionByte(Some(0))))

执行层数据在 Erigon 的 datadir 里,没有动。旧的 Lighthouse datadir 只是改名备份,然后用 Gnosis 的 checkpoint sync 重新启动 Lighthouse:

--checkpoint-sync-url https://checkpoint.gnosischain.com

Gnosis 文档给出了这个 checkpoint sync server;Lighthouse 文档也建议使用 checkpoint sync,因为它比从 genesis 开始同步快很多,同时提供同样的 beacon node 功能 [3][4]

还有一个旧参数需要去掉。新版 Lighthouse 不接受下面两个参数同时出现:

--checkpoint-sync-url ...
--allow-insecure-genesis-sync

既然用了 checkpoint sync,就不再需要 genesis sync 的旧参数。

真正让连接恢复的改动

Lighthouse v8.2.0 正常启动后,仍然报:

InvalidToken("HTTP status client error (403 Forbidden) for url (http://gnosis:8551/)")

这里最有用的是 403 Forbidden

Lighthouse 的 endpoint 是 http://gnosis:8551,也就是 Docker 网络里的服务名。Erigon 已经监听 0.0.0.0:8551,但 authrpc vhost 没有允许 gnosis 这个 Host。于是把 Erigon 启动参数改成:

--authrpc.addr=0.0.0.0
--authrpc.port=8551
--authrpc.vhosts=gnosis,localhost,127.0.0.1
--authrpc.jwtsecret=/jwt/jwt.hex

然后只重启 Erigon 容器,复用原来的 /data/erigon 和同一个 JWT 文件。

最后的启动形态

Erigon 侧:

erigon
  --chain=gnosis
  --datadir=/data
  --externalcl
  --authrpc.addr=0.0.0.0
  --authrpc.port=8551
  --authrpc.vhosts=gnosis,localhost,127.0.0.1
  --authrpc.jwtsecret=/jwt/jwt.hex
  --prune.mode=archive

Lighthouse 侧:

lighthouse bn
  --network gnosis
  --datadir /data
  --execution-endpoint http://gnosis:8551
  --execution-jwt /jwt/jwt.hex
  --checkpoint-sync-url https://checkpoint.gnosischain.com

最后的检查

Erigon 重启后,日志里出现了关键行:

[GetClientVersionV1] Received request fromClientCode: LH, Lighthouse-v8.2.0...

Lighthouse 的日志也从 JWT 错误变成正常的 Engine API 流程:

Execution engine online
Issuing forkchoiceUpdated
Synced ... exec_hash: ... (unverified)
Head is optimistic

最近日志里的错误计数也变成了 0:

docker logs --since 2m gnosis-lighthouse 2>&1 | grep -c 'InvalidToken'
# 0

这里的 Head is optimistic 是可以接受的中间状态。它表示 Lighthouse 已跟上 consensus head,但 execution layer 还在验证对应 payload。Erigon 日志里还能看到 Execution stage 在继续执行区块,所以剩下的是执行层追块,不是 Engine API 认证失败。

这次最值得记住的一点是:Lighthouse 日志写 InvalidToken 时,要继续看里面包着的 HTTP status。Erigon 返回 403 时,JWT 文件可能完全没问题,真正卡住的是 authrpc host allowlist。

参考

[1] Erigon README: Beacon Chain / Consensus Layer

[2] Lighthouse v8.2.0 release notes

[3] Gnosis Chain docs: Lighthouse checkpoint sync

[4] Lighthouse Book: run a node and checkpoint sync