spring-projects/spring-ai · error · OpenAIIoException
Could not read content length
Error message
Could not read content length
What it means
When converting an internal request body into an OkHttp RequestBody, SpringAiOpenAiHttpClient reads the body source's content length; an IOException while querying the length is wrapped in OpenAIIoException('Could not read content length').
Source
Thrown at models/spring-ai-openai/src/main/java/org/springframework/ai/openai/http/okhttp/SpringAiOpenAiHttpClient.java:349
private static String toBaseUrl(HttpUrl url) {
StringBuilder sb = new StringBuilder();
sb.append(url.scheme()).append("://").append(url.host());
if (url.port() != HttpUrl.defaultPort(url.scheme())) {
sb.append(':').append(url.port());
}
return sb.toString();
}
private static HttpRequestBody toHttpRequestBody(RequestBody source) {
final MediaType mediaType = source.contentType();
final String mediaTypeString = mediaType != null ? mediaType.toString() : null;
final long length;
try {
length = source.contentLength();
}
catch (IOException e) {
throw new OpenAIIoException("Could not read content length", e);
}
final boolean isOneShot = source.isOneShot();
return new HttpRequestBody() {
@Override
public @Nullable String contentType() {
return mediaTypeString;
}
@Override
public long contentLength() {
return length;
}
@Override
public boolean repeatable() {
return !isOneShot;
}View on GitHub (pinned to 98a7beda4f)
Solutions
- Check that the HttpRequestBody/stream you pass is open and readable at request-build time.
- Provide a body implementation whose content length is known (byte[] or file-backed) rather than a one-shot stream.
- Inspect the wrapped IOException cause to identify the failing source.
Example fix
// before HttpRequestBody body = HttpRequestBody.fromStream(streamThatMayBeClosed); // after byte[] bytes = stream.readAllBytes(); HttpRequestBody body = HttpRequestBody.fromBytes(bytes);
Defensive patterns
Strategy: validation
Validate before calling
// ensure the body is materialized and readable before the call
byte[] payload = bodyStream.readAllBytes();
if (payload.length == 0) { throw new IllegalStateException("Request body is empty/closed"); } Try / catch
try {
return client.execute(request, options);
} catch (OpenAIIoException e) {
if (e.getMessage().contains("content length")) {
throw new InvalidRequestBodyException("Body stream unreadable when building request", e);
}
throw e;
} Prevention
- Prefer byte[]/file-backed bodies over one-shot streams
- Do not close the body stream before the request is built
- Test custom HttpRequestBody implementations for repeatable length/read
When it happens
Trigger: Sending a request with a streaming/non-repeatable body whose source throws IOException when contentLength() is queried during toHttpRequestBody, called from toHttpRequest.
Common situations: Custom HttpRequestBody implementations backed by a stream that errors on length probing (e.g. a closed or pipe-backed stream), or a body whose source is consumed before the request is built.
Related errors
- Could not read content length
- Request failed
- Failed to write request body
- Invalid filename for file '': must be a single path segment
- Invalid filename for file '': ''
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/5825c3b798b08680.
Report an issue: GitHub.