{"record":{"id":"8fc65448f2699b75","repo":"BerriAI/litellm","slug":"polling-failed-response-text-8fc654","errorCode":null,"errorMessage":"Polling failed: {response.text}","messagePattern":"Polling failed: (.+?)","errorType":"exception","errorClass":"BlackForestLabsError","httpStatus":null,"severity":"error","filePath":"litellm/llms/black_forest_labs/image_generation/handler.py","lineNumber":348,"sourceCode":"        # BFL uses regional subdomains (e.g. gateway.bfl.ai) that differ from the\n        # submission host (api.bfl.ai), so we validate against the registered\n        # domain rather than doing a strict same-origin check. VERIA-51.\n        assert_bfl_polling_url(polling_url)\n\n        # Get just the auth header for polling\n        polling_headers: Final = {\"x-key\": headers.get(\"x-key\", \"\")}\n\n        start_time: Final = time.time()\n        verbose_logger.debug(\"BFL starting sync polling at %s\", polling_url)\n\n        while time.time() - start_time < max_wait:\n            response = sync_client.get(\n                url=polling_url,\n                headers=polling_headers,\n            )\n\n            if response.status_code != 200:\n                raise BlackForestLabsError(\n                    status_code=response.status_code,\n                    message=f\"Polling failed: {response.text}\",\n                )\n\n            data = response.json()\n            status = data.get(\"status\")\n\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(","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/black_forest_labs/image_generation/handler.py#L330-L366","documentation":"During the sync polling loop, each GET to the polling_url must return 200. A single non-200 poll (auth expiry mid-poll, 429 throttling, 5xx blips, or the polling URL expiring) aborts the loop and re-raises with the upstream status and body. The job may or may not still be running on BFL's side.","triggerScenarios":"Any poll response != 200 during the window: 401 if the key is invalidated mid-job, 429 when polling faster than BFL tolerates, 404 when the polling_url expires or the job record ages out, 5xx transient gateway errors.","commonSituations":"Aggressive polling intervals combined with BFL throttling; long-running jobs whose polling URLs expire; key rotation during an in-flight job; BFL incidents.","solutions":["Read the embedded response body — 429 means back off (raise interval), 404 means the job/URL expired (resubmit), 5xx means retry the whole call once.","Increase the polling interval so BFL is not throttling you.","For 401, verify the key is still valid; keys rotated mid-job kill polling auth.","Resubmit the generation — a dead polling session cannot be resumed through this API."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"from litellm.exceptions import APIError\n\ntry:\n    img = litellm.image_generation(model=M, prompt=p)\nexcept APIError as e:\n    sc = getattr(e, \"status_code\", None)\n    if sc == 429:\n        increase_interval_and_retry()\n    elif sc == 404:\n        return litellm.image_generation(model=M, prompt=p)  # URL expired -> resubmit\n    elif sc and sc >= 500:\n        return litellm.image_generation(model=M, prompt=p)\n    raise","preventionTips":["Poll at or above the default interval — faster polling invites 429s.","Don't rotate BFL keys while jobs are in flight; polling auth uses the submission key.","Resubmit rather than resume: expired polling URLs are not recoverable."],"tags":["bfl","polling","rate-limit","http-status","image-generation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}