BerriAI/litellm · error · BlackForestLabsError

Polling timed out after {max_wait} seconds

Error message

Polling timed out after {max_wait} seconds

What it means

The sync polling loop tracks elapsed time and raises 408 once `time.time() - start_time >= max_wait` without the job reaching a terminal status. The BFL job is likely still queued or processing — the client simply gave up first. No cancellation is sent upstream; the result may appear on BFL's side after you stopped asking.

Source

Thrown at litellm/llms/black_forest_labs/image_generation/handler.py:373

            verbose_logger.debug("BFL poll status: %s", status)

            if status == "Ready":
                return response
            elif status in [
                "Error",
                "Failed",
                "Content Moderated",
                "Request Moderated",
            ]:
                raise BlackForestLabsError(
                    status_code=400,
                    message=f"Image generation failed: {status}",
                )

            time.sleep(interval)

        raise BlackForestLabsError(
            status_code=408,
            message=f"Polling timed out after {max_wait} seconds",
        )

    async def _poll_for_result_async(
        self,
        initial_response: httpx.Response,
        headers: dict,
        async_client: AsyncHTTPHandler,
        max_wait: float = DEFAULT_MAX_POLLING_TIME,
        interval: float = DEFAULT_POLLING_INTERVAL,
        timeout: float | httpx.Timeout | None = None,
    ) -> httpx.Response:
        """
        Poll BFL API until result is ready (async version).
        """
        # Validate initial response status code
        if initial_response.status_code >= 400:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Raise the time budget: pass a larger timeout/max_wait via litellm_params or bump DEFAULT_MAX_POLLING_TIME in your fork/deployment.
  2. Lower concurrency per API key so jobs start sooner.
  3. Retry — resubmission after a timeout frequently completes faster than the stuck original.
  4. Pre-warm/tune prompt size and steps so jobs fit the window.

Example fix

# before
img = litellm.image_generation(model="black_forest_labs/flux-pro-1.1", prompt="...")

# after
img = litellm.image_generation(model="black_forest_labs/flux-pro-1.1", prompt="...", timeout=600)
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

import time

for attempt in range(2):
    try:
        return litellm.image_generation(model=M, prompt=p, timeout=600)
    except Exception as e:
        if getattr(e, "status_code", None) == 408 and attempt == 0:
            time.sleep(5)
            continue
        raise

Prevention

When it happens

Trigger: litellm.image_generation (sync) where the job stays in non-terminal statuses (e.g. 'Processing', 'Queued') beyond DEFAULT_MAX_POLLING_TIME, with `time.sleep(interval)` between polls.

Common situations: Peak-load queueing on BFL; high-step or large generations; many concurrent jobs on one key; defaults tuned for lighter workloads.

Understand the failure class

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/1807616f72ffd114. Report an issue: GitHub.