问题描述
在使用 go get
或 go mod tidy
时,可能会遇到以下错误:
1
2
3
4
5
# 错误 1
downloaded zip file too large
# 错误 2
create zip: module source tree too large
问题原因
错误 1:downloaded zip file too large
错误 1 是因为 go get
或者 go mod tidy
时,超过了下载 zip 文件的大小限制,默认大小为 500 << 20
,即 500MB。
- 描述:该错误是因为下载的 zip 文件大小超过默认限制 500MB (
500 << 20
)。 源代码逻辑:在
cmd/go/internal/modfetch/codehost/codehost.go
中,MaxZipFile
定义了下载 zip 文件的最大限制:1
const MaxZipFile = 500 << 20 // 解压文件最大限制为 500MB
触发流程:在下载模块 zip 文件时,函数检查文件总大小:这里的
repo.Zip
会调用LimitedReader
来控制读取的字节数。如果实际 zip 文件超过MaxZipFile
,就会触发错误信息downloaded zip file too large
。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
// src/cmd/go/internal/modget/get.go func init() { work.AddbuildFlags(CmdGet, work.OmitModFlag) CmdGet.Run = runGet // break init loop } func runGet(ctx context.Context, cmd *base.Command, args []string) { ... r.wrok.Add(func() { if _, err := modfetch.DownloadZip(ctx, mActual); err != nil { ... } }) ... } // src/cmd/go/internal/modfetch/fetch.go func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err error) { ... if err := downloadZip(ctx, mod, zipfile); err != nil { return cached{"", err} } ... } func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err error) { ... err := repo.Zip(f, mod.Version) ... } // src/cmd/go/internal/modfetch/coderepo.go func (r *codeRepo) Zip(dst io.Writer, version string) error { ... maxSize := int64(codehost.MaxZipFile) lr := &io.LimitedReader{R: dl, N: maxSize + 1} ... } // src/cmd/go/internal/modfetch/proxy.go func (p *proxyRepo) Zip(dst io.Writer, version string) error { ... lr := &io.LimitedReader{R: body, N: codehost.MaxZipFile + 1} ... } // src/cmd/go/internal/modfetch/codehost/codehost.go const ( MaxGoMod = 16 << 20 // maximum size of go.mod file MaxLICENSE = 16 << 20 // maximum size of LICENSE file MaxZipFile = 50000 << 20 // maximum size of downloaded zip file )
错误 2:create zip: module source tree too large
- 描述:此错误指解压后的模块源代码树大小超过默认的 500MB 限制。
源代码逻辑:解压文件大小限制由
cmd/vendor/golang.org/x/mod/zip/zip.go
中的MaxZipFile
定义:1
const MaxZipFile = 500 << 20 // 解压文件最大限制为 500MB
触发流程:在解压模块 zip 文件时,
Create
函数检查文件总大小:checkFiles
函数在解压模块时验证文件大小,如果超出MaxZipFile
限制,将返回module source tree too large
错误。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
// src/cmd/go/internal/modget/get.go func init() { work.AddbuildFlags(CmdGet, work.OmitModFlag) CmdGet.Run = runGet // break init loop } func runGet(ctx context.Context, cmd *base.Command, args []string) { ... r.wrok.Add(func() { if _, err := modfetch.DownloadZip(ctx, mActual); err != nil { ... } }) ... } // src/cmd/go/internal/modfetch/fetch.go func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err error) { ... if err := downloadZip(ctx, mod, zipfile); err != nil { return cached{"", err} } ... } func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err error) { ... err := repo.Zip(f, mod.Version) ... } // src/cmd/go/internal/modfetch/coderepo.go func (r *codeRepo) Zip(dst io.Writer, version string) error { ... return modzip.Create(dst, module.Version{Path: r.modPath, Version: version}, files) } // src/cmd/vendor/golang.org/x/mod/zip/zip.go const ( MaxZipFile = 500 << 20 MaxGoMod = 16 << 20 MaxLICENSE = 16 << 20 ) func Create(w io.Writer, m module.Version, files []File) (err error) { ... cf, validFiles, validSizes := checkFiles(files) ... } func checkFiles(files []File) (cf CheckedFiles, validFiles []File, validSizes []int64) { ... maxSize := int64(MaxZipFile) ... size := info.Size() if size >= 0 && size <= maxSize { maxSize -= size } else if cf.SizeError == nil { cf.SizeError = fmt.Errorf("module source tree too large (max size is %d bytes)", MaxZipFile) } ... }
解决方案
临时解决方案
通过修改 Go 源码的文件大小限制并重新编译 Go 来解决问题。
备份并修改源码路径:
1
mv $GOROOT $GOROOT.new
- 修改限制值:
打开
$GOROOT.new/src/cmd/go/internal/modfetch/codehost/codehost.go
,将MaxZipFile
修改为更大的值(例如 50GB):1
const MaxZipFile = 50000 << 20 // 将限制增大至 50GB
同时在
$GOROOT.new/src/cmd/vendor/golang.org/x/mod/zip/zip.go
中进行相同修改。
重新编译 Go:
1 2 3
cd $GOROOT.new/src/cmd/go go build -o go export GOROOT=$GOROOT.new
运行
go get
或go mod tidy
:1 2
$GOROOT.new/src/cmd/go/go get xxx $GOROOT.new/src/cmd/go/go mod tidy
永久解决方案
在原始 GOROOT 源码中修改后重新编译,使更改永久生效。
- 修改源码文件:
$GOROOT/src/cmd/go/internal/modfetch/codehost/codehost.go
$GOROOT/src/cmd/vendor/golang.org/x/mod/zip/zip.go
- 将
MaxZipFile
调整为更大值,例如 50GB。
重新编译 Go:
1 2
cd $GOROOT/src ./make.bash
- 使用
go get
或go mod tidy
即可正常运行。