Gemini-3.1-flash-tts-preview: streamGenerateContent truncates audio + finishReason: OTHER past ~60s, while generateContent (non-streaming) works

Summary: On gemini-3.1-flash-tts-preview, the SSE streaming endpoint (:streamGenerateContent?alt=sse) intermittently returns partial audio + finishReason: OTHER (HTTP 200) once the generation exceeds ~60s of audio. The exact same prompt through non-streaming :generateContent returns the full audio with finishReason: STOP every time. This bills AUDIO tokens for unusable output, with no error surfaced to the client.

Repro (raw REST, single-speaker, fr-FR voice “Leda”). Same request body, only the endpoint differs:

text ~audio :streamGenerateContent (3 trials) :generateContent
50 words ~20s STOP / STOP / STOP STOP
100 words ~40s STOP / STOP / STOP STOP
150 words ~57s STOP / STOP / STOP STOP
200 words ~70s OTHER / STOP / STOP STOP
250 words ~89s OTHER / STOP / STOP STOP
300 words ~106s OTHER / OTHER / OTHER STOP
350+ words ~125s OTHER / OTHER / OTHER STOP (full ~136s)

Streaming reliably truncates once the audio passes ~60-70s; non-streaming has no such cliff. Failures arrive as one/a few PCM chunks then finishReason: OTHER, HTTP 200.

The confusing part: the Gemini API TTS docs state “TTS does not support streaming” under Limitations, yet :streamGenerateContent accepts the request, returns 200, and bills AUDIO tokens, just with truncated output. What is the supported production path for long-form streaming TTS?

Environment: model gemini-3.1-flash-tts-preview; reproduced on both Vertex AI (generateContentStream) and the Gemini Developer API (streamGenerateContent?alt=sse); single-speaker; temperature omitted and 0.6 both reproduce.

Impact: production museum audio-guide product with long-form narration. We cannot ship the streaming path. Non-streaming works but a single ~136s generation takes ~77s wall-time, too slow for interactive playback. So today neither path is viable for >~1 min narration.

Related reports:

Could the Gemini API / TTS team confirm whether streaming TTS is supported and route the truncation? Happy to share full request/response payloads and responseIds.

Thanks for catching. We were able to reproduce and will work on a fix.

Hi Phil,

I hope everything is well. How is the fix coming along? If you need anything from my side please let me know, at the moment, I still encounter truncated audio consistently on long generations.

All the best,

Hendrik

Adding reproducible data from a production iOS app (museum audioguide, ~150-word French narrations, single speaker, REST streamGenerateContent SSE).

We ran two audits of all 30 prebuilt voices, same 141-word French text, ~2h apart (July 25):

  • Audit 1: 15/30 voices completed (finishReason STOP, 55-62 s audio). 15 truncated with OTHER at random points (8-58 s).
  • Audit 2 (same script, ~2h later): only 7/30 completed ‚Äî and the failing set was different: voices that passed audit 1 failed audit 2 and vice-versa (Zephyr, Leda, Callirrhoe, Enceladus flipped to failing; Fenrir, Umbriel flipped to passing).

So in our data the truncation is not voice-specific and not deterministic — random infra-level aborts, with failure rates varying ~50-75% depending on the hour. Only Aoede completed 8/8 across the whole day.

Two additional observations:

  1. Truncated responses still return HTTP 200 and we are billed for the AUDIO tokens of the unusable output.
  2. Chunking the text to ~70 words per request reduces but does not eliminate the aborts (8-24 s generations truncate too).

Current client-side mitigation: validate finishReason == STOP + audio duration vs word count, retry up to 3x. Works, but multiplies cost and latency.

Any update on the fix mentioned on June 23? Happy to share raw measurements.

Any updates on this? If any additional logs are required or an engineer wants to hop on a call, lets do it.

U got the same filter ?

Same problem on my side