Connection

UNAVAILABLE: connection refused

Your gRPC client got `Status { code: Unavailable }` with `connection refused` (or `transport is closing`). The TCP handshake never completed — either you're hitting the wrong port, TLS is misconfigured, or the endpoint is genuinely down.

Root causes

Ranked by frequency. First cause is the one to check first.

  1. 01Connecting to port 80/443 instead of the provider's actual gRPC port (Subglow uses 443 with TLS; some providers use a custom port).
  2. 02Missing TLS: you created a plaintext channel but the provider requires `grpcs://` / `use_tls=True`.
  3. 03The provider's endpoint is temporarily down — check the status page before assuming it's your code.
  4. 04Corporate firewall or Docker bridge network blocking outbound 443 (common on AWS Fargate and GCP Cloud Run with restrictive VPC).
  5. 05DNS resolution returning the wrong IP (happens during provider IP migrations).

Fix steps

  1. 1

    Confirm the endpoint and port

    Subglow is `grpc.subglow.io:443`. Always use TLS on 443. If you're on Helius use `mainnet.helius-rpc.com` with their own Laserstream config; Chainstack, Triton, and QuickNode each have their own host:port pair — copy it directly from their dashboard, don't guess.

  2. 2

    Enable TLS explicitly

    Most gRPC client libraries default to insecure. In the Yellowstone TypeScript client pass `{ 'grpc.ssl_target_name_override': 'grpc.subglow.io' }` and use `credentials.createSsl()`. In Python's grpc.aio use `grpc.secure_channel(url, grpc.ssl_channel_credentials())`. In Rust's yellowstone-grpc-client, pass `.tls_config(ClientTlsConfig::new())`.

  3. 3

    Test with grpcurl first

    Before debugging your client, run `grpcurl -H 'x-api-key: YOUR_KEY' grpc.subglow.io:443 geyser.Geyser/GetVersion`. If grpcurl works but your client doesn't, it's a client-side TLS or DNS issue, not a provider outage.

  4. 4

    Add reconnect with exponential backoff

    Even on healthy providers, gRPC streams get terminated periodically (validator restarts, regional failover). Wrap your SubscribeRequest in a loop with exponential backoff starting at 500ms and capped at 30s.

Code example

reconnect.tsts
import Client from "@triton-one/yellowstone-grpc";

async function streamWithReconnect() {
  let backoffMs = 500;
  while (true) {
    try {
      const client = new Client(
        "https://grpc.subglow.io:443",
        "YOUR_API_KEY",
        undefined,
      );
      const stream = await client.subscribe();
      backoffMs = 500; // reset on successful connect
      for await (const update of stream) {
        handle(update);
      }
    } catch (err) {
      console.error("stream closed:", err);
      await new Promise((r) => setTimeout(r, backoffMs));
      backoffMs = Math.min(backoffMs * 2, 30_000);
    }
  }
}

Provider-specific notes

  • Subglow
    All plans use `grpc.subglow.io:443` with TLS required. `x-api-key` header only — no basic auth fallback. Dedicated customers get a private hostname in Frankfurt or NY4.
  • Helius
    Laserstream uses a different endpoint than their Yellowstone fallback. Check your dashboard — connecting to the wrong one returns UNAVAILABLE with no useful error detail.

Related errors

Want an endpoint that just works?

Subglow is flat-priced Solana gRPC + JSON-RPC on a single API key. Pre-parsed JSON, dedicated sendTransaction bucket, 99.9% latency SLA on Dedicated. No credit juggling, no surprise bills.