Only fall back to a whole-blob download if the blob cannot be split - #30742
Closed
fmeum wants to merge 2 commits into
Closed
Only fall back to a whole-blob download if the blob cannot be split#30742fmeum wants to merge 2 commits into
fmeum wants to merge 2 commits into
Conversation
tyler-french
approved these changes
Aug 16, 2026
### Description `CombinedCache#downloadBlobFromRemote` falls back to downloading a blob as a whole when its chunked download fails with a `CacheNotFoundException`. That exception covers two very different situations: * the server cannot describe the blob as a sequence of chunks, which is raised by `getChunkDigests` before any data has been produced, and * one of the chunks is missing from the CAS, which is only discovered after the preceding chunks have already been written to the output stream. `ChunkedBlobDownloader` writes each chunk to the output stream as soon as it arrives and the stream cannot be rewound, so in the second case the fallback appended the entire blob to the chunks already written. Nothing catches this afterwards: there is no size or digest check over the final artifact, and `--remote_verify_downloads` doesn't help because the fallback wraps the stream in a fresh `DigestOutputStream` that only digests what the fallback itself writes. The result is a build artifact that is silently longer than its digest claims. The same applies to the other consumers of this code path, including `Tree` protos, in-memory outputs and stdout/stderr. The fallback is now keyed off a dedicated `BlobNotSplittableException`, which is only thrown before any chunk data has been produced. A missing chunk keeps propagating as a `CacheNotFoundException` and is handled like any other missing blob, so the outcome no longer depends on which chunk happens to be missing. `SplitBlob` returning `UNIMPLEMENTED` is now treated as "not splittable" as well. It previously turned into a plain `IOException`, so a server that advertises the parameters of a chunking function in its capabilities without implementing `SplitBlob` failed the build instead of falling back. ### Motivation Chunks have independent CAS lifetimes from the blob they belong to, so a chunk being evicted between `SplitBlob` and the read of that chunk is exactly the situation this fallback exists to handle. Recovering from it by restarting the download is only safe before any chunk has been handed to the caller. Found by inspection; requires `--experimental_remote_cache_chunking`. ### Build API Changes No ### Checklist - [x] I have added tests for the new use cases (if any). - [ ] I have updated the documentation (if applicable). ### Release Notes RELNOTES: None
fmeum
force-pushed
the
fix-chunked-download-partial-write
branch
from
August 17, 2026 08:40
e2a4cee to
9e1f98c
Compare
tyler-french
approved these changes
Aug 17, 2026
fmeum
marked this pull request as ready for review
August 18, 2026 09:16
Collaborator
Author
|
@bazel-io fork 9.3.0 |
tjgq
requested changes
Aug 19, 2026
tjgq
approved these changes
Aug 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
CombinedCache#downloadBlobFromRemotefalls back to downloading a blob as a whole when its chunked download fails with aCacheNotFoundException. That exception covers two very different situations:getChunkDigestsbefore any data has been produced, andChunkedBlobDownloaderwrites each chunk to the output stream as soon as it arrives and the stream cannot be rewound, so in the second case the fallback appended the entire blob to the chunks already written. Nothing catches this afterwards: there is no size or digest check over the final artifact, and--remote_verify_downloadsdoesn't help because the fallback wraps the stream in a freshDigestOutputStreamthat only digests what the fallback itself writes. The result is a build artifact that is silently longer than its digest claims. The same applies to the other consumers of this code path, includingTreeprotos, in-memory outputs and stdout/stderr.The fallback is now keyed off a dedicated
BlobNotSplittableException, which is only thrown before any chunk data has been produced. A missing chunk keeps propagating as aCacheNotFoundExceptionand is handled like any other missing blob, so the outcome no longer depends on which chunk happens to be missing.SplitBlobreturningUNIMPLEMENTEDis now treated as "not splittable" as well. It previously turned into a plainIOException, so a server that advertises the parameters of a chunking function in its capabilities without implementingSplitBlobfailed the build instead of falling back.Motivation
Chunks have independent CAS lifetimes from the blob they belong to, so a chunk being evicted between
SplitBloband the read of that chunk is exactly the situation this fallback exists to handle. Recovering from it by restarting the download is only safe before any chunk has been handed to the caller.Found by inspection; requires
--experimental_remote_cache_chunking.Build API Changes
No
Checklist
Release Notes
RELNOTES: None