bumptech/glide · error · IOException
Failed to read all expected data, expected: {contentLength},
Error message
Failed to read all expected data, expected: {contentLength}, but read: {readSoFar} What it means
Thrown by ContentLengthInputStream.checkReadSoFarOrThrow when the underlying stream returns end-of-stream (-1) but fewer bytes have been read than the Content-Length header declared. ContentLengthInputStream wraps an InputStream and verifies the byte count to catch truncated/corrupt network responses that would otherwise silently produce partial images.
Source
Thrown at library/src/main/java/com/bumptech/glide/util/ContentLengthInputStream.java:78
checkReadSoFarOrThrow(value >= 0 ? 1 : -1);
return value;
}
@Override
public int read(byte[] buffer) throws IOException {
return read(buffer, 0 /*byteOffset*/, buffer.length /*byteCount*/);
}
@Override
public synchronized int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
return checkReadSoFarOrThrow(super.read(buffer, byteOffset, byteCount));
}
private int checkReadSoFarOrThrow(int read) throws IOException {
if (read >= 0) {
readSoFar += read;
} else if (contentLength - readSoFar > 0) {
throw new IOException(
"Failed to read all expected data"
+ ", expected: "
+ contentLength
+ ", but read: "
+ readSoFar);
}
return read;
}
}
View on GitHub (pinned to eb14a895d8)
Solutions
- Add .error(fallbackDrawable) so the load degrades gracefully on truncation
- Retry the load with RequestBuilder.listener logging or a built-in retry via .thumbnail()/error(RequestBuilder)
- Investigate server/CDN: ensure Content-Length matches the actual body and that compression headers are consistent
- If using a custom OkHttpUrlLoader, configure OkHttp retries/timeouts and disable broken intermediate proxies
Example fix
// before
Glide.with(ctx).load(url).into(imageView) // crashes on truncated response
// after
Glide.with(ctx)
.load(url)
.error(R.drawable.fallback)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
Log.w(TAG, "Image load failed/truncated", e)
return false
}
override fun onResourceReady(...) = false
})
.into(imageView) Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot validate network truncation locally; rely on .error(fallback) + a listener. // Ensure server returns correct Content-Length and disable broken proxies.
Try / catch
Glide.with(ctx) .load(url) .error(R.drawable.fallback) .listener(loggingListener) .into(imageView) // Where loggingListener.onLoadFailed logs the GlideException root causes // (truncation appears as 'Failed to read all expected data...').
Prevention
- Always set .error(drawable) on network loads so truncation degrades gracefully
- Attach a RequestListener that logs root causes to diagnose truncation early
- Verify server Content-Length matches the body and is consistent with compression headers
- Configure OkHttp retries/timeouts if using a custom OkHttpUrlLoader
When it happens
Trigger: Any Glide network load (http/https URL model) where the server closes the connection before sending all the bytes advertised in Content-Length: proxy truncation, flaky mobile networks, server-side streaming bugs, or a misconfigured Content-Length header larger than the actual body.
Common situations: Spotty cellular/Wi-Fi dropping mid-download; CDN/proxy cache serving a truncated object; backend setting Content-Length incorrectly (e.g. with chunked encoding); server compression (gzip) without updating Content-Length.
Related errors
- Failed to get a response message
- File too large to map into memory
- File unsuitable for memory mapping
- Cannot reset to unset mark position
- Failed to connect or obtain data
AI-assisted analysis of bumptech/glide@eb14a895d8 (2026-08-14).
Data as JSON: /api/errors/b22da31f24bfcbdc.
Report an issue: GitHub.