{"record":{"id":"1807616f72ffd114","repo":"BerriAI/litellm","slug":"polling-timed-out-after-max-wait-seconds-180761","errorCode":null,"errorMessage":"Polling timed out after {max_wait} seconds","messagePattern":"Polling timed out after (.+?) seconds","errorType":"exception","errorClass":"BlackForestLabsError","httpStatus":408,"severity":"error","filePath":"litellm/llms/black_forest_labs/image_generation/handler.py","lineNumber":373,"sourceCode":"\n            verbose_logger.debug(\"BFL poll status: %s\", status)\n\n            if status == \"Ready\":\n                return response\n            elif status in [\n                \"Error\",\n                \"Failed\",\n                \"Content Moderated\",\n                \"Request Moderated\",\n            ]:\n                raise BlackForestLabsError(\n                    status_code=400,\n                    message=f\"Image generation failed: {status}\",\n                )\n\n            time.sleep(interval)\n\n        raise BlackForestLabsError(\n            status_code=408,\n            message=f\"Polling timed out after {max_wait} seconds\",\n        )\n\n    async def _poll_for_result_async(\n        self,\n        initial_response: httpx.Response,\n        headers: dict,\n        async_client: AsyncHTTPHandler,\n        max_wait: float = DEFAULT_MAX_POLLING_TIME,\n        interval: float = DEFAULT_POLLING_INTERVAL,\n        timeout: float | httpx.Timeout | None = None,\n    ) -> httpx.Response:\n        \"\"\"\n        Poll BFL API until result is ready (async version).\n        \"\"\"\n        # Validate initial response status code\n        if initial_response.status_code >= 400:","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/black_forest_labs/image_generation/handler.py#L355-L391","documentation":"Sync BFL polling exceeded `max_wait` (default DEFAULT_MAX_POLLING_TIME = 300 seconds) without the task reaching `Ready` or any terminal status, so the handler raises BlackForestLabsError(408). BFL generation is asynchronous - LiteLLM submits, then polls every ~1.5s - and heavily loaded queues can legitimately take longer than the 5-minute budget.","triggerScenarios":"Peak-hour queue backlog on BFL pushing a job past 300s; very slow settings (max prompts / high resolution / upscale-heavy models like flux-pro-1.1-ultra); many concurrent submissions from one key serializing server-side; the task stuck in `Queued`/`Processing` indefinitely after a platform incident.","commonSituations":"Batch generation jobs during evening load; single-threaded workers that submit several images in sequence, each nearing the budget; LiteLLM proxy setups where callers expect the OpenAI-style synchronous feel and time out at their own layer too.","solutions":["Retry the call - if the queue was merely slow, a resubmission often completes within budget.","Reduce load: lower concurrency per API key, or spread submissions over time.","If you control the handler call, pass a larger max_wait/polling budget where the plumbing exposes it, or wrap with your own retry-with-backoff.","Check BFL status for incidents when timeouts cluster across many jobs."],"exampleFix":"# before\nresp = litellm.image_generation(model=\"flux-pro-1.1-ultra\", prompt=very_complex_prompt)\n\n# after: retry with backoff for slow queues\nimport time\nfor attempt in range(3):\n    try:\n        resp = litellm.image_generation(model=\"flux-pro-1.1-ultra\", prompt=very_complex_prompt)\n        break\n    except Exception as e:\n        if getattr(e, \"status_code\", None) == 408 and attempt < 2:\n            time.sleep(10 * (attempt + 1))\n            continue\n        raise","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from litellm.llms.black_forest_labs.common_utils import BlackForestLabsError\n\nfor attempt in range(3):\n    try:\n        resp = litellm.image_generation(model=\"flux-pro-1.1\", prompt=p)\n        break\n    except BlackForestLabsError as e:\n        if e.status_code == 408 and attempt < 2:\n            time.sleep(15 * (attempt + 1))   # queue was slow; resubmit\n            continue\n        raise","preventionTips":["Budget for the 300s default polling window in your own caller timeouts.","Lower per-key concurrency so jobs spend less time queued.","Treat 408 as retryable but cap retries to avoid duplicating paid generations."],"tags":["litellm","black-forest-labs","flux","polling","timeout","async-job","sync"],"backgroundTag":"polling-timeout","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}