google-gemini/gemini-cli · error · FetchError

ETIMEDOUT

ETIMEDOUT

Error message

Request timed out after ${timeout}ms

What it means

The HTTP request exceeded the per-call timeout and was aborted internally; the abort is converted into a FetchError with code ETIMEDOUT so the retry layer can treat it as retryable. It only fires when the caller's own signal was not already aborted (user cancellation is re-thrown as a plain AbortError instead).

Solutions

  1. Increase the timeout argument for slow endpoints
  2. Let the retry layer re-attempt the request
  3. Check network/proxy latency or server responsiveness
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at packages/core/src/utils/fetch.ts:491 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of google-gemini/gemini-cli@6a466a7e2f (2026-09-16). Data as JSON: /api/errors/6d5f7e645de3a69d. Report an issue: GitHub.

Appendix: source

Thrown at packages/core/src/utils/fetch.ts:491

    if (!fetchOptions.dispatcher) {
      fetchOptions.dispatcher = currentProxy
        ? createSafeProxyAgent(currentProxy)
        : defaultSafeAgent;
    }

    const response = await fetch(url, fetchOptions);
    return response;
  } catch (error) {
    if (isAbortError(error)) {
      // If the caller's own signal was already aborted, this is a user-initiated
      // cancellation (e.g. Ctrl+C), not an internal timeout. Re-throw as a plain
      // AbortError so the retry layer does NOT treat it as a retryable ETIMEDOUT.
      if (options?.signal?.aborted) {
        // Rethrow the original abort reason or the caught error to preserve
        // the stack trace and any custom abort reason (e.g. from Ctrl+C).
        throw options.signal.reason ?? error;
      }
      throw new FetchError(`Request timed out after ${timeout}ms`, 'ETIMEDOUT');
    }
    if (error instanceof PrivateIpError) {
      throw error;
    }
    if (error && typeof error === 'object' && 'cause' in error) {
      if (error.cause instanceof PrivateIpError) {
        throw error.cause;
      }
    }
    throw new FetchError(getErrorMessage(error), undefined, { cause: error });
  } finally {
    clearTimeout(timeoutId);
  }
}

export function setGlobalProxy(proxy: string) {
  const trimmedProxy = proxy.trim();
  currentProxy = trimmedProxy;

View on GitHub (pinned to 6a466a7e2f)