cube-js/cube · critical

Connection check failed: ${errorMessage}

Error message

Connection check failed: ${errorMessage}

What it means

ClickHouseDriver.withCancel pings the ClickHouse server through @clickhouse/client before executing the wrapped query/callback. If the ping fails, the driver wraps the ping error (stringified, with special handling for AggregateError when the hostname resolves to multiple addresses) and throws 'Connection check failed: <error>'. It aborts before running user SQL so queries don't hit a dead connection.

Source

Thrown at packages/cubejs-clickhouse-driver/src/ClickHouseDriver.ts:222

    this.client = this.createClient(maxPoolSize);
  }

  protected withCancel<T>(fn: (con: ClickHouseClient, queryId: string, signal: AbortSignal) => Promise<T>): Promise<T> {
    const queryId = uuidv4();

    const abortController = new AbortController();
    const { signal } = abortController;

    const promise = (async () => {
      const pingResult = await this.client.ping();
      if (!pingResult.success) {
        // TODO replace string formatting with proper cause
        // pingResult.error can be AggregateError when ClickHouse hostname resolves to multiple addresses
        let errorMessage = pingResult.error.toString();
        if (pingResult.error instanceof AggregateError) {
          errorMessage = `Aggregate error: ${pingResult.error.message}; errors: ${pingResult.error.errors.join('; ')}`;
        }
        throw new Error(`Connection check failed: ${errorMessage}`);
      }
      signal.throwIfAborted();
      // Queries sent by `fn` can hit a timeout error, would _not_ get killed, and continue running in ClickHouse
      // TODO should we kill those as well?
      const result = await fn(this.client, queryId, signal);
      signal.throwIfAborted();
      return result;
    })();
    (promise as any).cancel = async () => {
      abortController.abort();
      // Use separate client for kill query, usual pool may be busy
      const killClient = this.createClient(1);
      try {
        await killClient.command({
          query: `KILL QUERY WHERE query_id = '${queryId}'`,
        });
      } finally {
        await killClient.close();

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Check the wrapped message: for AggregateError, look at the per-address errors to see which IP/cause failed
  2. Verify ClickHouse is reachable: curl http://<host>:8123/ping from the Cube process host
  3. Correct driver config (host, port, protocol http/https, username/password) in the constructor options
  4. Fix DNS/load-balancer so the resolved address is reachable, or pin a single resolvable address

Example fix

// before
const driver = new ClickHouseDriver({ host: 'http://clickhouse:8443' }); // wrong port/protocol
// after
const driver = new ClickHouseDriver({ host: 'https://clickhouse:8443' });
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight reachability check
const res = await fetch(`${host}/ping`).catch(() => null);
if (!res || !res.ok) {
  throw new Error(`ClickHouse unreachable at ${host}; check server/port/protocol`);
}

Try / catch

try {
  await cube.query(query);
} catch (e) {
  if (e.message.startsWith('Connection check failed:')) {
    if (e.message.includes('Aggregate error')) {
      // multi-address DNS issue: inspect per-address errors
    }
    // retry with backoff or fail fast on startup
  }
}

Prevention

When it happens

Trigger: query(), command(), or insert() calls when the initial ping to the ClickHouse host fails: server down, wrong host/port, TLS mismatch, DNS failure, or unreachable network from the container.

Common situations: ClickHouse container not started in docker-compose; wrong ClickHouseDriver host/port/protocol options; AggregateError when the hostname resolves to multiple IPs (e.g. headless service in k8s) with some unreachable; firewall blocking the native HTTP port 8123.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/efb6ed08515e9485. Report an issue: GitHub.