I’m seeing an unclear issue with Gemini TTS preview.
In my Python code I’m using the GenAI SDK, but I reproduced the same behavior with curl for simplicity.
The request asks for responseModalities: ["AUDIO"], voiceName: "Kore", and Hebrew text:
curl -sS -X POST 'https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-tts-preview:generateContent?key=REDACTED' \
-H 'Content-Type: application/json; charset=utf-8' \
--data-binary @- <<'JSON'
{"contents":[{"role":"user","parts":[{"text":"# AUDIO PROFILE: Nira\n## \"The Gentle Bedtime Storyteller\"\n\n## THE SCENE: A Quiet Bedroom at Night\nIt is bedtime in a calm, dim room. The listener is a child who is safe, comfortable, and slowly getting sleepy. The story should feel warm, protective, and peaceful.\n\n### DIRECTOR'S NOTES\nStyle: Soft, intimate, warm Hebrew bedtime storytelling. Gentle vocal smile, never theatrical.\nPace: Slow and calm bedtime pace, with natural pauses between sentences and paragraphs.\nAccent: Natural Israeli Hebrew.\n\n#### TRANSCRIPT\n\n[serenity]\nיואב והילד הקשיבו יחד לצרצרים וללילה השקט מסביב.\n\n[hope]\nאחרי כמה רגעים,\nשאל יואב:\n\"אתה זוכר משהו ליד הבית שלך?\nעץ, שער, אולי צבע של דלת?\"\n\nהילד חשב מעט,\nואז הרים את הראש.\n\n\"יש לנו שער ירוק,\"\nהוא אמר,\n\"ולידו עציץ גדול עם פרחים לבנים.\"\n\n[positive]\nיואב חייך אליו חיוך קטן.\n\"זה סימן מצוין,\"\nהוא אמר.\n\"נחפש שער ירוק ועציץ עם פרחים לבנים.\"\n\n[amusement]\nהילד חייך חיוך קטן ראשון ליד הפנס שעל האבן.\n\n[relaxation]\nיואב הושיט לו יד,\nוהילד אחז בה בזהירות.\n\nהם התחילו ללכת יחד בשביל,\nצעד אחר צעד,\nכשהפנס מאיר לפניהם אור קטן ורך.\n\n[serenity]\nהם עברו ליד גדר עץ נמוכה,\nליד תיבת דואר כחולה,\nוליד ספסל קטן מתחת לעץ חרוב.\n\nואז,\nבקצה הרחוב,\nראו שער ירוק.\n\nליד השער הירוק עמד עציץ גדול עם פרחים לבנים בדיוק כמו שהילד זכר.\n\n[relief]\n\"זה הבית שלי,\"\nאמר הילד בשמחה שקטה,\nכאילו הוא מפחד להעיר את הלילה.\n\nהאור בחלון הבית נדלק,\nוהדלת נפתחה לאט.\n\n[affection]\n\n[relief]\nאמא של הילד יצאה החוצה,\nראתה אותו,\nורצה אליו בצעדים מהירים ורכים.\n\nהיא כרעה לידו,\nעטפה אותו בזרועותיה,\nולחשה:\n\"כל כך דאגתי לך.\"\n\nאמו של הילד חיבקה אותו חזק ליד השער הירוק והעציץ עם הפרחים הלבנים.\n\n[neutral]\nיואב עמד בצד,\nהחזיק את הפנס הקטן,\nוחייך בשקט.\n\nהוא שמח שהילד חזר הביתה,\nאבל לא חיכה שיאמרו לו משהו מיוחד."}]}],"generationConfig":{"responseModalities":["AUDIO"],"speechConfig":{"voiceConfig":{"prebuiltVoiceConfig":{"voiceName":"Kore"}}}}}
JSON
The response is HTTP 200 and includes usageMetadata, but there is no audio payload:
{
"candidates": [
{
"content": {},
"finishReason": "OTHER",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 713,
"candidatesTokenCount": 5516,
"totalTokenCount": 6229
},
"modelVersion": "gemini-3.1-flash-tts-preview",
"responseId": "7AUMau3-BoTensEPrN7G-QQ"
}
A retry of the same request produced the same issue:
{
"finishReason": "OTHER",
"promptTokenCount": 713,
"candidatesTokenCount": 5609,
"responseId": "GQoMarHXDJzknsEPgq3O6Qg"
}
The confusing part is that this is not an HTTP/API error, but the response has no inlineData.data audio payload even though audio tokens appear in usageMetadata.
Is finishReason: OTHER with empty content expected for Gemini TTS preview? If so, what usually causes it and how should it be handled?
Update:
I was able to reproduce this with the exact same request.
The same payload sometimes returns:
{
"finishReason": "OTHER",
"content": {},
"usageMetadata": {
"promptTokenCount": 713,
"candidatesTokenCount": 5516
}
}
and later the same request succeeds:
{
"finishReason": "STOP",
"usageMetadata": {
"promptTokenCount": 713,
"candidatesTokenCount": 4925
}
}
So this does not look deterministic. The request is for Gemini TTS preview, responseModalities: ["AUDIO"], voiceName: "Kore", Hebrew text.
Is this expected behavior for the preview TTS model? Should clients treat finishReason: OTHER with empty content as a retryable no-audio failure, or does it indicate something wrong with the prompt/request?