One night I was reworking a script that feeds an app promo video to Gemini, and a forum thread stopped me. Someone had sent a roughly 23-second MP4 in agentic mode, waited several minutes, and received an HTTP 500 whose body said "high demand."
I knew video analysis was heavy. Still, waiting minutes and failing on 23 seconds felt off. Below I lay out the report, compare it with the official guidance on modes, and describe how I would decide between waiting, splitting and dropping to static mode before a failure arrives, as an indie developer who would rather not retry blindly.
I should say up front that I have not reproduced this failure. The report section summarizes the thread, and the code was exercised against simulated failures, not the live API.
What the report says
The thread was posted on September 17, 2026.
On September 16 the author uploaded a roughly 23-second MP4 through the Files API and sent it to /v1beta/interactions with processing set to agentic. Two attempts on gemini-3.8-flash and one on gemini-3.7-flash all ended in HTTP 500 after several minutes, with no analysis returned. Authentication and upload worked.
The saved 3.7 error body said the model was "currently experiencing high demand" and that spikes are usually temporary. The author adds that they cannot tell whether everyone is affected.
On September 18 a staff reply asked for a project ID or request ID and the prompt by direct message. The thread does not confirm a root cause, a known incident, or a workaround. A separate thread from September 8 describes an HTTP 200 turning into an api_error after 23 processing calls.
So all I can say is that this has been reported. Whether it is congestion or something about the input is not known.
What the docs say about the modes
Rereading the video understanding page, one point stood out.
Agentic mode is described as a fit for videos longer than about 5 to 10 minutes and for questions about specific moments. For short clips or broad questions it can increase time to first token and total tokens because of navigation reasoning and tool round-trips. Static mode is recommended for videos under about 5 minutes, full summaries, latency-sensitive work and frame-level precision.
A 23-second clip sits on the static side of that guidance. I am not claiming the mode caused the failure; congestion could have hit static requests too. But before thinking "it may pass if I wait," it is worth asking whether the mode was needed at all.
The same page recommends streaming or background execution for long jobs, and says synchronous requests that hit backend retries under high demand may come back as 401 Unauthorized or time out. A synchronous call that ends in a 500 or 401 after minutes fits that warning.
Decide the forks before the failure
Once a failure appears, the reflex is to send the same request again, and the waiting piles up. So I decide the next move per situation in advance.
| Situation | First move | Why |
|---|---|---|
| Agentic used on a video under 5 minutes | Switch to static | The docs place that length on the static side |
| Long video, agentic returns 500 or 503 | Double the wait and retry once or twice | Congestion is often temporary, and an instant resend hits the same wall |
| Agentic failed twice in a row | Read a clipped range in static mode | Clipping is available in static mode only |
| 4xx other than 401 | Do not retry; fix the input | Waiting cannot repair it |
I treat 401 as an exception. If the call was synchronous, switch to background=True first and watch again.
A helper that changes course by failure type
The script picks the first mode from the length, waits only on 500, 503 and 504, and drops to static after two agentic failures. Replace call(mode) with your own API call.
#!/usr/bin/env python3
"""Look at the failure type and decide the next move: wait, drop to static, or give up."""
import random
import time
RETRYABLE = {500, 503, 504}
AGENTIC_MIN_SECONDS = 300 # docs: static suits clips under about 5 minutes
def choose_mode(duration_s, needs_frame_precision=False):
"""Pick the first mode."""
if needs_frame_precision or duration_s < AGENTIC_MIN_SECONDS:
return "static"
return "agentic"
def run_with_fallback(call, duration_s, needs_frame_precision=False,
max_wait_s=600, sleep=time.sleep):
"""call(mode) returns text. The next move depends on the failure type."""
mode = choose_mode(duration_s, needs_frame_precision)
log, waited, delay = [], 0, 20
while True:
try:
return mode, call(mode), log
except Exception as e:
code = getattr(e, "code", None)
log.append((mode, code))
if code not in RETRYABLE:
raise # auth and input errors do not fix themselves by waiting
agentic_fails = sum(1 for m, _ in log if m == "agentic")
if mode == "agentic" and agentic_fails >= 2:
mode = "static" # do not hit the same road a third time
continue
if waited + delay > max_wait_s:
raise
sleep(delay + random.uniform(0, delay / 4))
waited += delay
delay *= 2I kept call injectable so the retry policy stays apart from the API call. That lets me test the forks with simulated failures without touching the live API.
Running it against simulated failures
I built a fake call that always raises 500 in agentic mode and succeeds in static, and passed it a 900-second video:
('static', [('agentic', 500), ('agentic', 500)]) waits 1
static agentic static
401 passed through: HTTP 401After two agentic failures it switched to static, with a single wait. A 23-second clip starts in static, a 15-minute video starts in agentic, and a 15-minute video that needs frame precision starts in static. A 401 is raised without a retry. This only confirms the policy. Whether the order helps during real congestion, I have not verified.
Pitfalls
Dropping to static does not work as-is for long videos. Static costs roughly 100 tokens per second at low resolution, so a long video sent whole gets large. When agentic will not pass on a long video, clipping with start_offset and end_offset is more realistic. Clipping and fps are static-only.
Also keep the request ID, the time and the mode for every failure. In the thread, that was the first thing staff asked for. Without a record, retries leave nothing to investigate together.
To confirm agentic actually ran, look for processing_call and processing_result in the response steps. That helps when a run looks suspiciously cheap.
For splitting retryable failures from ones that need a person, see the 429 retry design. Choosing length and fps is covered in timestamped video understanding.
What to do next
Open your video-analysis calls and check whether agentic is set only on videos that really exceed 5 minutes. If a short one carries it, switching back to static may cut both the waiting and the failures.
Before deciding whether to wait, decide whether the mode is needed. I plan to keep that line.