{"record":{"id":"e2dcdba011dc0049","repo":"vercel/ai","slug":"cannot-connect-to-api-cause-message","errorCode":null,"errorMessage":"Cannot connect to API: ${cause.message}","messagePattern":"Cannot connect to API: (.+?)","errorType":"exception","errorClass":"APICallError","httpStatus":null,"severity":"error","filePath":"packages/provider-utils/src/get-from-api.ts","lineNumber":152,"sourceCode":"      });\n    } catch (error) {\n      if (error instanceof Error) {\n        if (isAbortError(error) || APICallError.isInstance(error)) {\n          throw error;\n        }\n      }\n\n      throw new APICallError({\n        message: 'Failed to process successful response',\n        cause: error,\n        statusCode: response.status,\n        url,\n        responseHeaders,\n        requestBodyValues: {},\n      });\n    }\n  } catch (error) {\n    throw handleFetchError({ error, url, requestBodyValues: {} });\n  }\n};\n","sourceCodeStart":134,"sourceCodeEnd":155,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/provider-utils/src/get-from-api.ts#L134-L155","documentation":"getFromApi wraps low-level fetch failures (TypeError 'fetch failed' / 'failed to fetch' with a cause, or network errors with codes like ECONNREFUSED, ETIMEDOUT, UND_ERR_CONNECT_TIMEOUT) into an APICallError with message 'Cannot connect to API: <cause>' and isRetryable: true. It means the SDK could not establish a connection to the provider URL at all — no HTTP response was received.","triggerScenarios":"Any getFromApi call (e.g. provider downloads of images/audio/files, polling URLs) where fetch throws: DNS failure, server unreachable, proxy blocking egress, IPv6/IPv4 issues in Node 18+ undici, TLS interception, or the process lacking network access.","commonSituations":"Corporate proxy/firewall without HTTPS_PROXY configuration; offline CI runners; wrong baseURL pointing at a non-existent host; self-hosted gateway (e.g. LiteLLM/vLLM) not started; Node 18+ undici preferring IPv6 in Docker containers; missing root CA in corporate environments.","solutions":["Read error.cause (the original network error) for the specific code: ECONNREFUSED means the host/port is down; ENOTFOUND means DNS; certificate errors mean TLS interception.","Verify network reachability: curl the same URL from the same machine/container to isolate SDK vs environment.","Configure proxy support (undici ProxyAgent / global dispatcher with HTTPS_PROXY) behind corporate firewalls.","Check DNS/IPv6 issues in Docker by forcing IPv4 (NODE_OPTIONS='--dns-result-order=ipv4first' or Node >=20 default).","Implement retry with backoff — the error is flagged isRetryable: true — for transient connection drops."],"exampleFix":"// before (no proxy config in corp network)\nconst provider = createOpenAI();\n// after\nimport { ProxyAgent, setGlobalDispatcher } from 'undici';\nif (process.env.HTTPS_PROXY) {\n  setGlobalDispatcher(new ProxyAgent(process.env.HTTPS_PROXY));\n}\nconst provider = createOpenAI();","handlingStrategy":"retry","validationCode":"// before the call\nconst url = new URL(targetUrl);\nawait fetch(url.origin + '/health', { signal: AbortSignal.timeout(3000) }).catch(e => { throw new Error(`Endpoint unreachable: ${e.cause?.code ?? e.message}`); });","typeGuard":"import { APICallError } from '@ai-sdk/provider';\nfunction isConnectionError(e: unknown): e is APICallError {\n  return APICallError.isInstance(e) && e.message.startsWith('Cannot connect to API:');\n}","tryCatchPattern":"try {\n  const { value } = await getFromApi({ url, successfulResponseHandler });\n} catch (error) {\n  if (APICallError.isInstance(error) && error.message.startsWith('Cannot connect to API:') && error.isRetryable) {\n    // exponential backoff retry; after N attempts check network/proxy/DNS\n  }\n  throw error;\n}","preventionTips":["Smoke-test provider URLs with curl from the same runtime/container before deploying.","Configure proxy agents (HTTPS_PROXY + undici ProxyAgent) in corporate networks.","Use ipv4first DNS ordering in Docker to avoid undici IPv6 black-holing.","Monitor dependency image base for current CA certificates (TLS interception causes 'unable to verify' causes).","Wrap provider fetches in retry logic since the SDK marks these errors isRetryable."],"tags":["network","fetch-failed","connection","dns","proxy"],"backgroundTag":"cannot-connect-to-api","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}