redis/node-redis · error · Error

TLS certificates not available after ${maxWaitMs}ms

Error message

TLS certificates not available after ${maxWaitMs}ms

What it means

waitForTlsCertificates polls `docker exec <id> test -f <file>` for ca.crt, <cert>.crt, and <cert>.key every 100ms, retrying until all exist or maxWaitMs (default 30000ms) elapses. On timeout it throws. It gates loadTlsCertificates so that reads only happen once the container's cert generation completes.

Source

Thrown at packages/test-utils/lib/dockers.ts:321

    `${DEFAULT_TLS_PATH}/${certName}.key`,
  ];

  while (Date.now() - startTime < maxWaitMs) {
    try {
      await Promise.all(
        certFiles.map(file =>
          execAsync("docker", ["exec", dockerId, "test", "-f", file]),
        ),
      );
      // All files exist
      return;
    } catch {
      // Not all files exist yet, wait and retry
      await setTimeout(100);
    }
  }

  throw new Error(`TLS certificates not available after ${maxWaitMs}ms`);
}

/**
 * Spawns a TLS-enabled Redis server Docker container with both TLS and non-TLS ports
 */
export async function spawnTlsRedisServerDocker(
  options: RedisServerDockerOptions,
  serverArguments: Array<string> = [],
  tlsConfig?: TlsConfig,
): Promise<TlsRedisServerDocker> {
  const port = (await portIterator.next()).value;
  const tlsPort = (await portIterator.next()).value;
  const clientCertCN = tlsConfig?.clientCertCN;

  // Use provided CN for cert name, otherwise use default 'client' cert
  const certName = clientCertCN ?? DEFAULT_CLIENT_CERT_NAME;

  const dockerArgs = [

View on GitHub (pinned to 90fd0652bc)

Solutions

  1. Inspect the container logs for the cert-generation step: docker logs <id>
  2. Pass a larger maxWaitMs if the environment is slow
  3. Verify the certName/clientCertCN matches a cert the image actually produces (default is 'client')

Example fix

// before — default 30s budget exceeded
await waitForTlsCertificates(dockerId, certName);

// after — allow more time on slow CI
await waitForTlsCertificates(dockerId, certName, 60_000);
Defensive patterns

Strategy: retry

Validate before calling

async function safeWaitForTls(dockerId: string, certName: string, maxWaitMs = 60_000): Promise<void> {
  try {
    await waitForTlsCertificates(dockerId, certName, maxWaitMs);
  } catch (e) {
    const logs = await execAsync('docker', ['logs', dockerId]).then(r => r.stderr, () => '');
    throw new Error(`${(e as Error).message}\nContainer logs:\n${logs}`);
  }
}

Try / catch

try {
  await waitForTlsCertificates(dockerId, certName, 60_000);
} catch (e) {
  if (e instanceof Error && /TLS certificates not available/.test(e.message)) {
  }
  throw e;
}

Prevention

When it happens

Trigger: The Redis image failed to generate TLS certificates within 30s (cert-gen script errored or is absent); the container crashed mid-startup; the certName (clientCertCN) does not match the files the image produces.

Common situations: Slow CI disk making cert generation lag; image variant without the TLS bootstrap script; custom clientCertCN that the image does not materialize; clock/resource contention on a loaded runner.

Understand the failure class

Related errors


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/9d64de571baa199e. Report an issue: GitHub.