FuelLabs/fuels-ts · error · FuelError

CONNECTION_REFUSED

CONNECTION_REFUSED

Error message

Unable to fetch chain and node info from the network

What it means

Thrown by Provider's getChainAndNodeInfo flow when the underlying GraphQL operation to fetch chain and node info rejects for any reason. The .catch wraps the original error in a FuelError coded CONNECTION_REFUSED, attaches metadata { url } and sets error.cause = { code: 'ECONNREFUSED' }, then rethrows. Note the cause is hardcoded as ECONNREFUSED regardless of the real underlying error.

Source

Thrown at packages/account/src/providers/provider.ts:858

        chain: deserializeChain(data.chain),
        nodeInfo: deserializeNodeInfo(data.nodeInfo),
        consensusParametersTimestamp: Date.now(),
      }))
      .then((data) => {
        Provider.setIncompatibleNodeVersionMessage(data.nodeInfo);
        Provider.chainInfoCache[this.urlWithoutAuth] = data.chain;
        Provider.nodeInfoCache[this.urlWithoutAuth] = data.nodeInfo;
        this.consensusParametersTimestamp = data.consensusParametersTimestamp;
        return data;
      })
      .catch((err) => {
        const error = new FuelError(
          FuelError.CODES.CONNECTION_REFUSED,
          'Unable to fetch chain and node info from the network',
          { url: this.urlWithoutAuth },
          err
        );
        error.cause = { code: 'ECONNREFUSED' };

        throw error;
      })
      .finally(() => {
        delete Provider.inflightFetchChainAndNodeInfoRequests[this.urlWithoutAuth];
      });

    // Set the inflight request to the network request
    Provider.inflightFetchChainAndNodeInfoRequests[this.urlWithoutAuth] =
      getChainAndNodeInfoFromNetwork;

    // Return the cached values once the network request resolves
    return Provider.inflightFetchChainAndNodeInfoRequests[this.urlWithoutAuth].then((data) => {
      this.consensusParametersTimestamp = data.consensusParametersTimestamp;
      return {
        nodeInfo: Provider.nodeInfoCache[this.urlWithoutAuth],
        chain: Provider.chainInfoCache[this.urlWithoutAuth],
      };

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Verify the fuel-core node is running and reachable: curl the provider URL's /health or GraphQL endpoint directly.
  2. Double-check the Provider URL (scheme, host, port, optional auth) matches the running node.
  3. Ensure network/firewall/DNS allows the connection; in a browser check CORS and mixed-content.
  4. Inspect err.cause / the wrapped original error (the third FuelError constructor arg) to find the true failure, since cause.code is hardcoded to ECONNREFUSED.
  5. Retry with backoff for transient network blips; implement a reconnection strategy for long-lived clients.

Example fix

// before
const provider = new Provider('http://127.0.0.1:4000'); // node not running
await provider.getChain(); // throws CONNECTION_REFUSED

// after
// 1) start fuel-core, then:
const provider = new Provider('http://127.0.0.1:4000');
try {
  await provider.getChain();
} catch (e) {
  // e.cause.code is hardcoded 'ECONNREFUSED'; read e.metadata and the wrapped error
  console.error('real cause:', e.metadata, e);
}
Defensive patterns

Strategy: retry

Validate before calling

async function assertNodeReachable(url: string) {
  const res = await fetch(url, { method: 'GET' });
  if (!res.ok && res.status !== 405) throw new Error(`node not reachable at ${url}`);
}
await assertNodeReachable(providerUrl);
const provider = new Provider(providerUrl);

Type guard

import { FuelError } from '@fuel-ts/errors';
const isConnectionRefused = (e: unknown): boolean =>
  e instanceof FuelError && e.code === FuelError.CODES.CONNECTION_REFUSED;

Try / catch

import { FuelError } from '@fuel-ts/errors';
async function withRetry<T>(fn: () => Promise<T>, retries = 3): Promise<T> {
  for (let i = 0; ; i++) {
    try { return await fn(); }
    catch (e) {
      if (e instanceof FuelError && e.code === FuelError.CODES.CONNECTION_REFUSED && i < retries) {
        await new Promise(r => setTimeout(r, 250 * 2 ** i));
        continue;
      }
      throw e;
    }
  }
}
// usage:
const chain = await withRetry(() => provider.getChain());

Prevention

When it happens

Trigger: Calling any Provider method that triggers getChainAndNodeInfo (e.g. provider.init(), provider.getChain(), or the first operation requiring cached chain/node info) when the GraphQL request to the node fails — network down, wrong URL, node not running, TLS failure, DNS failure, malformed response, or any rejection from this.operations.getChainAndNodeInfo().

Common situations: fuel-core node not started or crashed. Wrong provider URL (typo, missing port, http vs https, auth segment malformed). Firewall/network blocking the port. Node still booting when the SDK connects. CORS in browser. Self-signed cert rejected. DNS resolution failure. The hardcoded ECONNREFUSED cause can mislead diagnosis when the real cause differs (e.g. HTTP 404, parse error).

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/9746c6ee583571cb. Report an issue: GitHub.