spring-projects/spring-ai · error · RuntimeException

Failed to read audio speech response

Error message

Failed to read audio speech response

What it means

OpenAiAudioSpeechModel.call() reads the entire HTTP response body of the OpenAI text-to-speech endpoint into memory via InputStream.readAllBytes(). If the stream throws an IOException mid-read (connection dropped, read timeout, connection reset), the method wraps it in a RuntimeException with this message, indicating the audio bytes could not be fully retrieved.

Source

Thrown at models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioSpeechModel.java:143

		Assert.notNull(prompt, "Prompt must not be null");

		OpenAiAudioSpeechOptions mergedOptions = mergeOptions(prompt);
		String inputText = getInputText(prompt, mergedOptions);
		traceRequest("Calling", mergedOptions);

		SpeechCreateParams params = buildSpeechCreateParams(mergedOptions, inputText, false);

		RequestOptions requestOptions = this.buildRequestOptions(mergedOptions);

		HttpResponse httpResponse = this.openAiClient.audio().speech().create(params, requestOptions);
		Headers headers = httpResponse.headers();

		byte[] audioBytes;
		try (InputStream inputStream = httpResponse.body()) {
			audioBytes = inputStream.readAllBytes();
		}
		catch (IOException e) {
			throw new RuntimeException("Failed to read audio speech response", e);
		}

		if (audioBytes.length == 0) {
			if (logger.isWarnEnabled()) {
				logger.warn("No speech response returned for prompt: " + prompt);
			}
			return new TextToSpeechResponse(List.of(new Speech(new byte[0])));
		}

		Speech speech = new Speech(audioBytes);
		OpenAiAudioSpeechResponseMetadata metadata = OpenAiAudioSpeechResponseMetadata.from(headers);

		return new TextToSpeechResponse(List.of(speech), metadata);
	}

	@Override
	public Flux<TextToSpeechResponse> stream(TextToSpeechPrompt prompt) {
		Assert.notNull(prompt, "Prompt must not be null");

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Retry the speech request, ideally with exponential backoff — transient network drops are the most common cause.
  2. Enable response streaming / increase read timeouts on the underlying RestClient/ WebClient used by the OpenAI client.
  3. Check proxy/firewall idle-timeout settings and disable response buffering for large audio payloads.
  4. Verify OpenAI service status and reduce request size (shorter prompt, different voice/format) to shorten transfer time.
  5. Inspect the wrapped IOException cause to distinguish timeout vs connection-reset vs premature EOF.

Example fix

// before
byte[] audio = openAiAudioSpeechModel.call(new SpeechPrompt(longText));
// after
byte[] audio;
try {
    audio = openAiAudioSpeechModel.call(new SpeechPrompt(longText));
}
catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Failed to read audio speech response")) {
        audio = retryWithBackoff(() -> openAiAudioSpeechModel.call(new SpeechPrompt(longText)));
    } else { throw e; }
}
Defensive patterns

Strategy: retry

Try / catch

try {
    SpeechResponse response = speechModel.call(prompt);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Failed to read audio speech response") && attempt < 3) {
        // backoff and retry; transient IO failure reading the audio stream
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: The HTTP connection to the OpenAI speech endpoint is interrupted while streaming the audio bytes: network drop, proxy closing the connection, read timeout on a long/slow TTS generation, or the server aborting the response mid-transfer.

Common situations: Generating long audio files over unstable networks or corporate proxies with idle timeouts; Docker/Kubernetes environments where connections are dropped after ~30-60s; OpenAI API incidents; very large speech requests that exceed proxy body limits and cause the upstream to cut the stream.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/58e6341f361d2548. Report an issue: GitHub.