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
- Retry the speech request, ideally with exponential backoff — transient network drops are the most common cause.
- Enable response streaming / increase read timeouts on the underlying RestClient/ WebClient used by the OpenAI client.
- Check proxy/firewall idle-timeout settings and disable response buffering for large audio payloads.
- Verify OpenAI service status and reduce request size (shorter prompt, different voice/format) to shorten transfer time.
- 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
- Configure generous read/response timeouts on the RestClient used by the OpenAI client.
- For long prompts, split the text to keep each response transfer short.
- Check proxy idle timeouts and disable response buffering for audio endpoints.
- Implement idempotent retry with exponential backoff around TTS calls.
- Monitor the IOException cause to distinguish timeout vs reset vs premature EOF.
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
- Failed to read resource:
- Request failed
- Failed to write request body
- Request failed
- Failed to write request body
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/58e6341f361d2548.
Report an issue: GitHub.