Conversation
isArchive() decides whether stdin carries a build context or a raw
Dockerfile by sniffing magic bytes. The table knows bzip2, gzip, xz and
plain tar, but not zstd, so a zstd-compressed context piped to
'docker build -' is parsed as a Dockerfile and the build fails on line 1:
$ echo 'FROM scratch' > Dockerfile
$ tar cf ctx.tar Dockerfile && zstd -q ctx.tar -o ctx.tar.zst
$ docker build --check - < ctx.tar.zst
1 | >>> (\u2572/\u2572d '5 \u2572F`i...
gzip and plain tar on the same path work.
The daemon already decompresses zstd build contexts - verified against
Docker Engine 29.7.2 by building the same tar.zst context through the
/build API directly - so only the client-side sniff rejects it today.
This adds the zstd frame magic to the table and a unit test covering
all supported formats.
Related: moby/go-archive#13
Signed-off-by: nrvate <11264848+nrvate@users.noreply.github.com>
crazy-max
requested changes
Sep 15, 2026
Member
There was a problem hiding this comment.
I initially thought moby/buildkit#7069 covered this, but Buildx needs to recognize the archive before uploading it, so this fix is needed.
I’ve extracted a shared compression.IsArchive helper from moby/buildkit#7034 in moby/buildkit#7148, including zstd skippable-frame support. Once that lands and we vendor it here, we can replace Buildx local detector with the shared helper and cover zstd contexts with a stdin integration test. That should keep the two implementations from drifting again.
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.
Problem
docker build -decides whether stdin carries a build context or a raw Dockerfile by sniffing magic bytes (isArchiveinbuild/utils.go). The table knows bzip2, gzip, xz and plain tar — but not zstd. A zstd-compressed context on stdin is therefore parsed as a Dockerfile and the build fails immediately:gzip and plain tar on the same path work.
Fix
Add the zstd frame magic (
0x28, 0xB5, 0x2F, 0xFD) to the table. Nothing else changes: for the default docker driver the stream is passed through to the daemon, and the daemon already decompresses zstd build contexts — verified against Docker Engine 29.7.2 by building the same tar.zst context through the/buildAPI directly (it succeeds today; only this client-side sniff rejects it).Testing
TestIsArchivecovering plain tar, gzip, bzip2, xz, zstd, a Dockerfile-from-stdin negative, and a truncated-magic negativego test ./build/ -run TestIsArchivepasses (Go 1.26, per go.mod)Related: moby/go-archive#13 (broader zstd support in the archive library — this PR is the narrower client-side sniff gap).