Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
RPC 故障排查阅读约 13 分钟

RPC 方法未找到(-32601):命名空间与端点能力

为什么同一个 JSON-RPC 调用在一个端点上返回 -32601,在另一个端点上却成功,以及如何以编程方式探测命名空间的可用性。

TL;DR

JSON-RPC 错误 -32601(方法未找到)是 JSON-RPC 2.0 规范中预定义的错误码,当方法不存在或在该端点上不可用时返回。在实践中它有两个截然不同的原因:方法名确实未知(拼写错误、链方言错误、客户端分叉特有的方法),或者方法存在于客户端中但被端点有意不暴露,例如被禁用的 debug、trace、admin 或 txpool 命名空间。由于公共和共享端点通常出于成本和安全的考虑禁用昂贵的命名空间,-32601 通常是对端点能力的说明,而不是你代码中的 bug。本文解释了命名空间模型,展示了一个可运行的 Node.js 能力探测脚本,并提供了结果表、决策指南和故障排查清单,让你能够发现端点实际支持什么,而不是靠猜测。

JSON-RPC 2.0 规范中的 -32601 错误码

JSON-RPC 2.0 规范在第 5.1 节中定义了一小组预定义的错误码。错误码 -32601 保留给“方法未找到”,当请求的方法不存在或不可用时返回。这一句话包含了你在区块链 RPC 中会遇到的两个原因:方法名可能对服务器来说是未知的,或者方法可能存在于服务器软件中但对你的请求不可用。

规范并不要求服务器解释这两种情况中的哪一种适用。错误对象可能包含带有额外细节的 data 字段,但许多实现只返回错误码和简短消息。这就是为什么同一个调用在一个端点上成功,在另一个端点上却以 -32601 失败:该错误码描述的是端点的响应,而不是你的应用程序逻辑的有效性。

以太坊 JSON-RPC 规范在此基础上将方法分组到命名空间中,例如 eth、net、web3、debug、trace、txpool 和 admin,某些 L2 和 Parity 衍生客户端上还有额外的命名空间。命名空间归属是一种约定,而不是暴露的保证。一个端点可以完整实现 eth 命名空间,但对每个 debug 和 trace 调用都返回 -32601。

  • 权威来源:JSON-RPC 2.0 规范,第 5.1 节(错误对象和预定义错误码)。
  • 权威来源:以太坊 JSON-RPC 规范(方法命名空间和方法定义)。
  • -32601 表示“未找到或不可用”——它不区分这两种情况。

两种截然不同的原因都会表现为 -32601

第一个原因是方法名确实未知。这包括拼写错误和大小写错误、调用属于不同链方言的方法,或调用仅存在于特定客户端分叉上的方法。例如,一个执行客户端添加的方法可能在另一个客户端中不存在,L2 可能暴露 L1 不暴露的命名空间。如果名称错误,任何端点配置都无法修复。

第二个原因是方法存在于客户端软件中,但被端点有意不暴露。运营商出于成本、安全和稳定性原因禁用命名空间。debug 或 trace 调用可能比简单读取昂贵几个数量级,而 admin 方法可以改变节点状态。当命名空间在网关或节点配置层面被禁用时,该方法实际上是不可见的,服务器正确地返回 -32601。

区分这两者很重要,因为补救措施不同。拼写错误在你的代码中修复。被禁用的命名空间通过更换端点、更换节点类型或更换调用的方法来修复。当 -32601 是能力说明时却把它当作代码 bug 处理,会导致浪费调试时间。

  • 名称未知:拼写错误、大小写错误、链方言错误、仅客户端分叉的方法。
  • 方法不可用:命名空间被禁用、非归档节点、提供商套餐限制。
  • 仅凭错误负载通常无法判断适用哪种原因——通过探测来查明。

为什么共享和公共端点禁用 debug、trace、admin 和 txpool

公共和共享端点通常禁用 debug、trace、admin 和 txpool 命名空间。原因有据可查,且在各提供商之间一致:trace 和 debug 调用每次请求可能消耗大量 CPU 和内存,admin 方法可以改变节点行为,txpool 检查会暴露运营商可能不希望公开的 mempool 数据。禁用这些命名空间可以保护所有用户的端点。

每个提供商具体暴露哪些命名空间是按提供商记录的,并且因提供商、套餐甚至区域而异。没有通用的表格。提供商可能在付费层启用 trace 而在免费层禁用,或者在一个链上启用 txpool 而在另一个链上不启用。这就是为什么实用技能不是记住表格,而是以编程方式发现能力。

关于端点选择和托管 RPC 预期的更广泛指引,请参阅 RPC 端点指南(RPC Assistant)。如果你的工作负载特别依赖 trace 和 debug,以太坊 trace 和 debug 命名空间一文深入介绍了这些方法,以太坊 txpool 命名空间一文介绍了 mempool 检查。

  • 成本:trace 和 debug 调用每次请求都很昂贵。
  • 安全:admin 方法可以改变节点状态;txpool 暴露 mempool 数据。
  • 稳定性:禁用重型命名空间可以保护共享容量。
  • 暴露情况按提供商记录,并因提供商、套餐和链而异。

在应用程序启动时运行的能力探测

由于 JSON-RPC 中没有标准化的能力发现调用,可靠的方法是探测。探测是一小组廉价调用,每个你依赖的命名空间一个,在启动时执行。首先用低成本方法(如 eth_chainId 或 net_version)证明连通性。然后尝试每个所需命名空间中的一个代表性方法,并记录结果。

下面的示例使用 Node.js 和内置的 fetch API,因此没有依赖。它调用 eth_chainId 确认端点可达,然后用一个方法分别探测 eth、net、web3、debug、trace、txpool 和 admin。它记录每次尝试的错误码和消息,并打印摘要。对每个你正在考虑的端点运行它,并比较输出。

保持探测列表小而廉价。不要在生产端点上以高频率使用昂贵方法(如 debug_traceTransaction)进行探测。启动时每个命名空间一次调用就足以了解该命名空间是否存在。

// capability-probe.js — Node.js 18+ (built-in fetch, no dependencies)
const ENDPOINT = process.env.RPC_URL || "https://your-endpoint.example";

// One cheap, representative method per namespace.
const PROBES = [
  { ns: "eth",    method: "eth_chainId",            params: [] },
  { ns: "net",    method: "net_version",           params: [] },
  { ns: "web3",   method: "web3_clientVersion",    params: [] },
  { ns: "debug",  method: "debug_traceTransaction", params: ["0x" + "00".repeat(32)] },
  { ns: "trace",  method: "trace_block",           params: ["latest"] },
  { ns: "txpool", method: "txpool_status",         params: [] },
  { ns: "admin",  method: "admin_peers",           params: [] }
];

async function call(method, params) {
  const body = { jsonrpc: "2.0", id: 1, method, params };
  const res = await fetch(ENDPOINT, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(body)
  });
  const json = await res.json();
  return { http: res.status, json };
}

(async () => {
  // Step 1: prove connectivity with a low-cost call.
  const ping = await call("eth_chainId", []);
  if (ping.json.error) {
    console.error("Endpoint unreachable or rejecting requests:", ping.json.error);
    process.exit(1);
  }
  console.log("Connected. chainId =", ping.json.result);

  // Step 2: probe each namespace and record the outcome.
  const rows = [];
  for (const p of PROBES) {
    try {
      const { http, json } = await call(p.method, p.params);
      const err = json.error;
      rows.push({
        namespace: p.ns,
        method: p.method,
        http,
        code: err ? err.code : "ok",
        message: err ? err.message : "success",
        enabled: err ? "n" : "y"
      });
    } catch (e) {
      rows.push({
        namespace: p.ns,
        method: p.method,
        http: "network-error",
        code: "-",
        message: String(e),
        enabled: "?"
      });
    }
  }

  console.table(rows);
  const missing = rows.filter(r => r.code === -32601).map(r => r.namespace);
  if (missing.length) {
    console.warn("Namespaces returning -32601:", missing.join(", "));
  }
})();

静态能力元数据与探测的对比

一些提供商发布静态能力元数据:文档表格、能力端点或机器可读清单,列出每条链支持的命名空间。当它存在时,是一个有用的起点。但暴露情况会在没有通知的情况下变化。提供商可能启用一个命名空间,在事件期间禁用它,或将其移到某个套餐层之后。上个季度准确的文档表格今天可能是错的。

探测更可靠,因为它测量的是你实际使用的端点,在你使用它的那一刻。权衡是探测列表必须随着链添加命名空间而手动维护。JSON-RPC 中没有标准化的能力发现调用,因此你的探测列表是一个活的产物。把静态元数据当作文档,把探测当作验证。

一个实用的模式是结合两者:阅读提供商记录的能力来构建初始探测列表,然后在启动时运行探测并记录结果。如果探测与文档不一致,相信探测并向提供商报告差异。

  • 静态元数据:阅读快速,但可能过时或特定于套餐。
  • 探测:对你面前的端点具有权威性,但需要维护。
  • 结合两者:用文档做计划,用探测做验证。

命名空间可用性、节点类型和归档要求

命名空间可用性不是唯一的门槛。节点类型也很重要。历史状态方法,例如在旧区块上调用 eth_getBalance 或对历史区块调用 debug_traceTransaction,即使命名空间已启用,也需要归档节点。全节点会修剪旧状态,因此方法可能存在且命名空间可能开启,但调用会失败,因为请求的区块不再可用。

在许多情况下,这会产生与 -32601 不同的错误,通常是缺少 trie 节点或状态不可用的消息。但实际教训是一样的:成功探测一个命名空间并不能保证该命名空间中的每个方法对每个区块高度都有效。如果你的应用程序需要历史状态,请将归档可用性与命名空间可用性分开确认。

对于基于 Substrate 的链,运行时元数据和版本控制增加了另一个维度;Substrate state_getMetadata 和运行时版本一文介绍了元数据调用在运行时升级中的行为。这个原则可以推广:能力有层次——命名空间、节点类型和链状态。

  • 命名空间已启用 + 全节点 = 历史状态方法仍可能失败。
  • 命名空间已启用 + 归档节点 = 历史状态方法更可能成功。
  • 先探测命名空间,然后用历史区块调用验证归档行为。

传输限制:HTTP 与 WebSocket 订阅

传输是另一个能力层。在常见的以太坊 JSON-RPC 实现中,订阅方法(如 eth_subscribe 和 eth_unsubscribe)仅支持 WebSocket。如果你通过 HTTP 发送 eth_subscribe,即使 eth 命名空间完全启用,端点也可能返回 -32601。该方法不可用不是因为命名空间关闭,而是因为该传输方式不可用。

这是一个常见的混淆来源,因为同一个端点可能在不同 URL 上同时提供 HTTP 和 WebSocket。如果你的探测通过 HTTP 运行并报告 eth 已启用,这并不能告诉你订阅是否有效。请专门通过 WebSocket 传输探测订阅,或查看提供商文档中的订阅 URL。

一般规则:能力探测必须使用你的应用程序将使用的相同传输方式。HTTP 探测验证 HTTP 方法。WebSocket 探测验证订阅。不要从一种推断另一种。

  • eth_subscribe 和 eth_unsubscribe 通常仅支持 WebSocket。
  • 即使 eth 已启用,HTTP 也可能对订阅方法返回 -32601。
  • 通过你将在生产中实际使用的传输方式进行探测。

为你自己的端点制作按命名空间的结果表

使用下表记录你的每个端点实际支持什么。通过针对每个端点运行前面部分中的探测,并将错误码和消息复制到表中来填写。每个环境(开发、预发布、生产)保留一张表,因为暴露情况可能因套餐和区域而异。

“已启用”列是你的结论,而不是原始错误码。-32601 表示该方法在该传输方式下未启用。成功表示已启用。网络错误表示未知——在得出结论前重试。备注列用于记录上下文,例如“需要归档”或“仅 WebSocket”。

  • 命名空间 | 方法 | 错误码 | 消息 | 已启用(y/n) | 备注
  • eth | eth_chainId | | | |
  • net | net_version | | | |
  • web3 | web3_clientVersion | | | |
  • debug | debug_traceTransaction | | | | 历史区块需要归档节点
  • trace | trace_block | | | |
  • txpool | txpool_status | | | |
  • admin | admin_peers | | | |
  • eth (ws) | eth_subscribe | | | | 仅 WebSocket 传输

决策指南:更换方法、更换端点还是更换节点类型

一旦你有了探测结果,决策通常很直接。如果方法名错误——拼写错误、大小写错误或来自另一条链方言的方法——更换方法。在假设端点有问题之前,对照以太坊 JSON-RPC 规范或相关链的文档验证确切名称。

如果方法名正确而命名空间返回 -32601,更换端点。选择记录了你所需命名空间的提供商或套餐。对于以太坊主网端点,networks/eth 页面列出了可用网络,RPC 定价描述了套餐层级与命名空间访问的关系。如果你正在构建需要保证命名空间访问的服务,API 服务页面介绍了托管访问选项。

如果命名空间已启用但历史调用失败,将节点类型更换为归档节点。如果订阅通过 HTTP 失败,将传输方式更换为 WebSocket。这些都是针对能力栈不同层的不同修复方法。

  • 方法名错误 → 在代码中修复方法。
  • 名称正确但返回 -32601 → 更换端点或套餐。
  • 命名空间开启但历史调用失败 → 更换为归档节点。
  • 订阅通过 HTTP 失败 → 将传输方式更换为 WebSocket。

-32601 故障排查清单

按顺序完成此清单。它从最便宜的检查到最昂贵的检查,这样你就不会为一个一个字符就能解决的问题而更换基础设施。

如果这些都无法解决错误,那么端点确实不暴露该命名空间。此时适用上面的决策指南。关于端点选择和常见集成问题的更广泛演练,OnFinality Learn 中心收集了相关指南,迁移已弃用的 Solana RPC 方法一文展示了特定方法移除在实践中如何表现。

  • 逐字符对照规范比较方法名,包括大小写。
  • 确认你没有通过 HTTP 调用订阅方法。
  • 检查代理、负载均衡器或网关是否剥离或重写了请求路径。
  • 重试一次,以排除表现为 JSON-RPC 错误的瞬时路由 404。
  • 验证端点 URL 指向你想要的链,而不是测试网或其他网络。
  • 运行能力探测并记录确切的错误码和消息。
  • 如果命名空间已启用,测试一个历史区块以检查归档可用性。

能力发现的局限性和权衡

JSON-RPC 中没有标准化的能力发现调用。规范定义了错误码和方法语义,但没有定义列出支持方法的调用。这意味着每个能力探测都是手动维护的列表。随着链添加命名空间——例如新的 L2 特定命名空间或客户端分叉方法——你的探测列表必须更新以覆盖它们。

提供商也可能对它打算稍后添加的方法返回 -32601。该方法今天不可用,但这种缺失是路线图状态,而不是永久限制。探测告诉你当前真相;它不告诉你提供商的计划。对于规划,将探测结果与提供商发布的路线图或支持渠道结合起来。

最后,探测会增加启动延迟和少量请求。对大多数应用程序来说这可以忽略不计,但对于延迟敏感的服务,你可能希望缓存探测结果并定期刷新,而不是在每次进程启动时刷新。权衡在于新鲜度和启动成本之间。

  • JSON-RPC 中不存在标准化的能力发现调用。
  • 随着链添加命名空间,探测列表必须手动维护。
  • -32601 可能表示提供商计划稍后添加的方法。
  • 如果启动延迟很重要,请缓存探测结果。

可靠命名空间集成的后续步骤

首先对你环境中的每个端点运行能力探测,并填写结果表。这一项练习就能把猜测转化为有记录的能力图。然后将结果编码到应用程序的启动检查中,这样缺失的命名空间会快速失败并给出清晰消息,而不是在请求处理程序深处表现为神秘的 -32601。

如果你的工作负载依赖 trace、debug 或 txpool,请查看关于以太坊 trace 和 debug 命名空间以太坊 txpool 命名空间的专门文章,以了解这些方法的成本和数据特征。如果你仍在选择端点,RPC 端点指南(RPC Assistant)RPC 定价页面可帮助你根据命名空间需求匹配套餐层级。

持久的习惯很简单:永远不要假设命名空间可用。探测它,记录它,并在更换端点或套餐时重新探测。这个习惯将 -32601 从令人困惑的失败转变为关于端点能力的清晰、可操作的信号。

  • 对每个端点运行探测并记录结果。
  • 添加启动检查,在命名空间缺失时快速失败。
  • 在任何端点或套餐变更后重新探测。
  • 使用 OnFinality Learn 中心获取相关集成指南。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始