Skip to content

Live session dies with 1011 keepalive ping timeout immediately after first turn_complete (reproducible across gemini-3.1-flash-live-preview, gemini-2.5-flash-native-audio-latest) #2935

Open

Description

@himanshu0749

Is this a client library issue or a product issue?

Unclear — could be either. The client sends audio correctly with no errors or gaps right up until the disconnect, so the failure appears to originate server-side (the Live backend closing the socket), but I'm filing here first since it reproduces consistently against this SDK's live.connect() / send_realtime_input() API surface. Happy to redirect to Cloud Support if maintainers determine it's purely backend.

Environment details

  • Programming language: Python
  • OS: macOS
  • Language runtime version: <! --python 3.12.14 -->
  • Package version:

Steps to reproduce

  1. Open a Live session with response_modalities: ["AUDIO"] and input_audio_transcription: {} (automatic VAD, default settings — no manual activity_start / activity_end / audio_stream_end calls).
  2. Stream microphone audio continuously via send_realtime_input(audio=...) in ~100ms PCM chunks (16kHz, 16-bit mono, audio/pcm;rate=16000).
  3. Speak one short utterance (e.g. "Hello").
  4. Model replies with audio (model_turn parts, mime_type=audio/pcm;rate=24000) and correctly sends turn_complete.
  5. Continue streaming mic audio as before — no pause, no manual stream-end signal.
  6. Within roughly one send cycle after turn_complete, the next send_realtime_input call raises:

Activity

  1. added
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    priority: p2Moderately-important priority. Fix may not be included in next release.
    on Sep 3, 2026
  2. Venkaiahbabuneelam commented on Sep 3, 2026

    @Venkaiahbabuneelam

    Hi @himanshu0749, Thanks for reaching out us!
    To help us understand the issue, could you please share a code snippet of what you've tried so far?
    Thanks

  3. himanshu0749 commented on Sep 5, 2026

    @himanshu0749
    Author

    Sure — here's a minimal repro:

    import os
    import asyncio
    import queue
    import sounddevice as sd
    
    from dotenv import load_dotenv
    from google import genai
    from google.genai import types
    
    load_dotenv()
    
    api_key = os.getenv("GEMINI_API_KEY")
    client = genai.Client(api_key=api_key)
    
    MODEL = "gemini-3.1-flash-live-preview"  # also reproduces on gemini-2.5-flash-native-audio-latest
                                              # and gemini-2.5-flash-native-audio-preview-12-2025
    
    SAMPLE_RATE = 16000
    CHANNELS = 1
    CHUNK_FRAMES = 1600  # 100 ms
    
    
    async def main():
        async with client.aio.live.connect(
            model=MODEL,
            config={
                "response_modalities": ["AUDIO"],
                "input_audio_transcription": {},
            },
        ) as session:
    
            print("Connected")
    
            audio_queue = queue.Queue(maxsize=20)
    
            def mic_callback(indata, frames, time_info, status):
                if status:
                    print(f"Mic status: {status}")
                audio_bytes = indata.copy().tobytes()
                try:
                    audio_queue.put_nowait(audio_bytes)
                except queue.Full:
                    try:
                        audio_queue.get_nowait()
                        audio_queue.put_nowait(audio_bytes)
                    except queue.Empty:
                        pass
    
            async def send_microphone():
                with sd.InputStream(
                    samplerate=SAMPLE_RATE,
                    channels=CHANNELS,
                    dtype="int16",
                    blocksize=CHUNK_FRAMES,
                    callback=mic_callback,
                ):
                    while True:
                        try:
                            audio_bytes = await asyncio.to_thread(audio_queue.get, timeout=0.5)
                        except queue.Empty:
                            continue
    
                        # No gaps observed here before the crash — instrumented
                        # separately with timestamps, sends were continuous.
                        await session.send_realtime_input(
                            audio=types.Blob(
                                data=audio_bytes,
                                mime_type="audio/pcm;rate=16000",
                            )
                        )
    
            async def receive_gemini():
                async for response in session.receive():
                    if not response.server_content:
                        continue
    
                    server_content = response.server_content
    
                    if server_content.input_transcription and server_content.input_transcription.text:
                        print(f"You: {server_content.input_transcription.text}")
    
                    if server_content.model_turn:
                        for part in server_content.model_turn.parts:
                            if part.inline_data:
                                print(f"Gemini audio chunk: {len(part.inline_data.data)} bytes")
    
                    if server_content.turn_complete:
                        print("turn_complete received")
    
            await asyncio.gather(
                send_microphone(),
                receive_gemini(),
            )
    
    
    if __name__ == "__main__":
        asyncio.run(main())

    Running this: speak one short utterance, Gemini replies fully (transcription + all audio chunks arrive, turn_complete prints), then the very next send_realtime_input call in send_microphone() raises:

    websockets.exceptions.ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received
    

    google-genai version: <Name: google-genai Version: 2.22.0 Summary: GenAI Python SDK Home-page: https://github.com/googleapis/python-genai Author: Author-email: Google LLC <[email protected]> License-Expression: Apache-2.0>

    Happy to share a full terminal log if useful.

  4. kkorpal commented on Sep 8, 2026

    @kkorpal

    Hi @himanshu0749, thanks for the reproduction script! We ran it locally and confirmed the exact behavior: the backend unexpectedly drops the WebSocket with a 1011 error immediately after the first turn_complete. I've escalated this directly to the Live API engineering team to investigate the server-side disconnects. Thanks for flagging this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions