Go version
go version go1.24.4 darwin/arm64
Output of go env
in your module/workspace:
AR='ar'
CC='cc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='c++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/Users/carlos/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/carlos/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/qj/36_tzh_54kj9mm0lhlhy3f900000gn/T/go-build3621002674=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/carlos/Developer/goreleaser/goreleaser/go.mod'
GOMODCACHE='/Users/carlos/Developer/Go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/carlos/Developer/Go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.24.4/libexec'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/carlos/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.24.4/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.24.4'
GOWORK=''
PKG_CONFIG='pkg-config'
What did you do?
Creating a zip archive using archive/zip
like so:
package main
import (
"archive/zip"
"compress/flate"
"io"
"os"
)
func main() {
fz, err := os.OpenFile("foo.zip", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0o644)
if err != nil {
panic(err)
}
z := zip.NewWriter(fz)
z.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
return flate.NewWriter(out, flate.BestCompression)
})
f, err := os.Open("main.go")
if err != nil {
panic(err)
}
fd, err := f.Stat()
if err != nil {
panic(err)
}
fh, err := zip.FileInfoHeader(fd)
if err != nil {
panic(err)
}
w, err := z.CreateHeader(fh)
if err != nil {
panic(err)
}
_, err = io.Copy(w, f)
if err != nil {
panic(err)
}
if err := z.Close(); err != nil {
panic(err)
}
}
Then, you run it, it should create a foo.zip
file.
From there, we can do things like:
$ busybox unzip -l foo.zip
Archive: foo.zip
Length Date Time Name
--------- ---------- ----- ----
715 06-13-2025 13:17 main.go
-------- -------
715 1 files
But, if you try to unzip it from a pipe:
$ cat foo.zip | busybox unzip -
Archive: -
unzip: zip flag 8 (streaming) is not supported
If we do the same with unzip
shipped by Apple on macOS, it only prints its own help.
My guess is that this line might be the culprit: https://cs.opensource.google/go/go/+/master:src/archive/zip/writer.go;l=359
It seems we're always setting the stream bit if the file isn't a directory...
What did you see happen?
unzip: zip flag 8 (streaming) is not supported
What did you expect to see?
Not to see that error.
Comment From: adonovan
Unlike tar ("tape archive") files of old, the design of zip files is inherently random-access due to the placement of the central directory at the end. While it is technically possible to create zip files from a stream of unknown files, I don't think that was ever considered in scope for archive/zip, and it's not possible to read any zip file without random access.
Comment From: cherrymui
cc @dsnet @bradfitz
Comment From: caarlos0
oh, that error is a bit confusing, then.
I thought the problem was that we were setting flag 8, which isn't supported, but it's the other way around, then? It's requiring flag 8, which is not set?
Comment From: neild
unzip: zip flag 8 (streaming) is not supported
I'm not sure where this error is coming from, but I'm pretty sure it's not archive/zip. I don't see anything which looks like that error text in the package.
This is not something I'm highly familiar with, but I believe it is possible in principle to decode at least some zip files from a stream. I'm not sure if archive/zip.Writer puts the necessary information in its output to do a streaming decode. archive/zip.Reader doesn't have any support for streaming decode; it always loads the archive's "central directory".
The "flag 8 is not supported" error sounds to me like the decoder (which I'm pretty sure is not archive/zip) lacks streaming support.
Comment From: caarlos0
The "flag 8 is not supported" error sounds to me like the decoder (which I'm pretty sure is not archive/zip) lacks streaming support.
It's coming from unzip
.
The error is a bit confusing, but I think it means that the zip file doesn't have the flag 8 set.
Comment From: gopherbot
Timed out in state WaitingForInfo. Closing.
(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)
Comment From: caarlos0
I don't know why this was closed? It got the "waiting for info" label but never asked for any extra info @seankhliao
Comment From: seankhliao
See for example https://github.com/richgel999/miniz/issues/180 It's busybox that doesn't support streaming.