unionlabs/union · warning · RpcStatusError

HTTP ${res.status} - ${res.statusText}

Error message

HTTP ${res.status} - ${res.statusText}

What it means

RpcStatusError raised by the nodes status page when probing a Cosmos RPC: it POSTs a JSON-RPC "status" request and the HTTP response is not ok (res.ok false). The message embeds the HTTP status code and status text from the node or gateway that answered.

Source

Thrown at app2/src/routes/nodes/+page.svelte:78

  url: string,
): Effect.Effect<RpcStatusResult, RpcStatusError> =>
  Effect.tryPromise({
    try: async signal => {
      if (type === "cosmos") {
        const { result: res, duration } = await withTiming(async () =>
          fetch(url, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              jsonrpc: "2.0",
              id: 1,
              method: "status",
              params: [],
            }),
          })
        )
        if (!res.ok) {
          throw new RpcStatusError("cosmos", url, `HTTP ${res.status} - ${res.statusText}`)
        }
        const data = await res.json()
        if (!(data?.result?.sync_info && data?.result?.node_info)) {
          throw new RpcStatusError("cosmos", url, "Malformed response", data)
        }
        return {
          url,
          type: "cosmos",
          responseTimeMs: duration,
          status: {
            kind: "cosmos",
            latestBlockHeight: Number(data.result.sync_info.latest_block_height),
            catchingUp: data.result.sync_info.catching_up,
            moniker: data.result.node_info.moniker,
            network: data.result.node_info.network,
          },
        }
      }

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Confirm the URL targets the CometBFT/Tendermint RPC endpoint (default port 26657) and answers POST / with a JSON-RPC body
  2. Open the URL in a browser/curl to see the exact status code and adjust (auth token, correct path, different provider)
  3. Reduce probe frequency or use a paid/private RPC to avoid 429s
Defensive patterns

Strategy: try-catch

Validate before calling

const isCometBftRpcCandidate = (url: string) => /^https?:\/\//.test(url) && !url.includes("26657") === false // explicit port check helps
// cheaper: validate reachability before adding to the list
await fetch(url, { method: "HEAD" }).catch(() => { /* mark endpoint suspicious before probing */ })

Try / catch

// The page already maps probes to RpcStatusError rows; wrap per-endpoint:
try {
  status = await checkCosmos(url)
} catch (error) {
  if (error instanceof RpcStatusError) {
    // render HTTP status in the node table; mark endpoint offline on 5xx, auth-issue on 401/403
  }
  throw error
}

Prevention

When it happens

Trigger: A Cosmos/CometBFT RPC URL returning 4xx/5xx: 404 (wrong path, endpoint is not a Tendermint RPC), 405 (GET-only route), 401/403 (auth-protected or geo-blocked node), 429 (rate limit), 502/503 (gateway or node down).

Common situations: Pasting a REST (1317) or gRPC (9090) port URL instead of the RPC (26657) port; public RPC endpoints that rate-limit bursts of probes; CORS/proxy front-ends returning HTML error pages with non-200 codes.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/2cd93e818a8db664. Report an issue: GitHub.