{"record":{"id":"2b67a513c482dc40","repo":"BerriAI/litellm","slug":"apitimeouterror-request-timed-out-error-str-e","errorCode":null,"errorMessage":"APITimeoutError - Request timed out. Error_str: {error_str}","messagePattern":"APITimeoutError - Request timed out\\. Error_str: (.+?)","errorType":"exception","errorClass":"Timeout","httpStatus":408,"severity":"error","filePath":"litellm/litellm_core_utils/exception_mapping_utils.py","lineNumber":2256,"sourceCode":"                pass\n\n            ################################################################################\n            # End of Common Extra information Needed for all providers\n            ################################################################################\n\n            ################################################################################\n            #################### Start of Provider Exception mapping ####################\n            ################################################################################\n\n            if (\n                \"Request Timeout Error\" in error_str\n                or \"Request timed out\" in error_str\n                or \"Timed out generating response\" in error_str\n                or \"The read operation timed out\" in error_str\n            ):\n                exception_mapping_worked = True\n\n                raise Timeout(\n                    message=f\"APITimeoutError - Request timed out. Error_str: {error_str}\",\n                    model=model,\n                    llm_provider=custom_llm_provider,\n                    litellm_debug_info=extra_information,\n                )\n\n            if (\n                custom_llm_provider == \"litellm_proxy\"\n            ):  # handle special case where calling litellm proxy + exception str contains error message\n                extract_and_raise_litellm_exception(\n                    response=getattr(original_exception, \"response\", None),\n                    error_str=error_str,\n                    model=model,\n                    custom_llm_provider=custom_llm_provider,\n                )\n            if (\n                custom_llm_provider == \"openai\"\n                or custom_llm_provider == \"text-completion-openai\"","sourceCodeStart":2238,"sourceCodeEnd":2274,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/litellm_core_utils/exception_mapping_utils.py#L2238-L2274","documentation":"Inside exception_type(), before provider-specific mapping, litellm string-matches the error text for 'Request Timeout Error', 'Request timed out', 'Timed out generating response', or 'The read operation timed out' and raises litellm.Timeout ('APITimeoutError - Request timed out. Error_str: ...'). This catches client/gateway timeout exceptions (openai.APITimeoutError, httpx read timeouts, vertex read timeouts) that surface as text rather than status codes.","triggerScenarios":"The HTTP client's own timeout elapsing before any provider response: openai-python APITimeoutError, httpx.ReadTimeout/WriteTimeout wrapped by a provider adapter, or provider SDKs whose timeout messages contain those phrases. Also triggered by user-supplied timeout= being smaller than generation time.","commonSituations":"Default 600s/short timeouts with very long generations; slow embeddings on large inputs; high-latency self-hosted/proxied endpoints; retrying heavy batch jobs with the same tiny timeout.","solutions":["Increase the timeout: litellm.completion(..., timeout=600) or litellm.timeout = 600 globally.","Use streaming so partial output arrives within the read window.","Reduce per-request work (max_tokens, input size) or parallelize smaller chunks instead of one giant call.","Enable num_retries so transient timeouts are retried automatically."],"exampleFix":"# before\nlitellm.completion(model=\"gpt-4o\", messages=big_msgs, timeout=30)\n\n# after\nlitellm.completion(\n    model=\"gpt-4o\",\n    messages=big_msgs,\n    timeout=600,\n    num_retries=3,\n)","handlingStrategy":"retry","validationCode":"# budget check: estimated generation time vs configured timeout\nest_tokens = litellm.token_counter(model=model, messages=msgs)\nassert timeout >= est_tokens / TOKENS_PER_SEC.get(model, 50), \"timeout smaller than expected generation time\"","typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.completion(**kwargs)\nexcept litellm.Timeout as e:\n    if \"APITimeoutError\" in str(e):\n        kwargs[\"timeout\"] = (kwargs.get(\"timeout\") or 60) * 2\n        kwargs[\"num_retries\"] = 2\n        resp = litellm.completion(**kwargs)\n    else:\n        raise","preventionTips":["Set litellm.timeout (or per-call timeout=) explicitly — never rely on defaults for long jobs.","Stream long generations; non-streaming waits pay the full latency in one window.","Enable num_retries for automatic timeout retries.","Token-count inputs to predict slow calls before making them."],"tags":["timeout","client-timeout","string-matching","litellm","exception-mapping"],"backgroundTag":"request-timeout","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}