unionlabs/union · warning · RpcStatusError
HTTP
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.
Solutions
- Confirm the URL targets the CometBFT/Tendermint RPC endpoint (default port 26657) and answers POST / with a JSON-RPC body
- Open the URL in a browser/curl to see the exact status code and adjust (auth token, correct path, different provider)
- 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
- Only list CometBFT RPC endpoints (port 26657 or provider equivalents) for cosmos probes
- Prefer endpoints with generous CORS and rate limits for browser probing
- Treat 429/5xx as transient (retry later) and 401/403/404 as configuration errors
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
- Malformed response
- No wallet available
- client info not found
- Denom must be between 2 and 128 characters
- Failed to download asset
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/2cd93e818a8db664.
Report an issue: GitHub.
Appendix: 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)