{"record":{"id":"a62d2a872858602b","repo":"goreleaser/goreleaser","slug":"failed-to-close-archive-file-s-w","errorCode":null,"errorMessage":"failed to close archive file %s: %w","messagePattern":"failed to close archive file (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pipe/archive/archive.go","lineNumber":199,"sourceCode":"\tarchivePath := filepath.Join(ctx.Config.Dist, folder+\".\"+format)\n\tlock.Lock()\n\tif err := os.MkdirAll(filepath.Dir(archivePath), 0o755|os.ModeDir); err != nil {\n\t\tlock.Unlock()\n\t\treturn err\n\t}\n\tif _, err = os.Stat(archivePath); !errors.Is(err, fs.ErrNotExist) {\n\t\tlock.Unlock()\n\t\treturn fmt.Errorf(\"archive named %s already exists. Check your archive name template\", archivePath)\n\t}\n\tarchiveFile, err := os.Create(archivePath)\n\tif err != nil {\n\t\tlock.Unlock()\n\t\treturn fmt.Errorf(\"failed to create directory %s: %w\", archivePath, err)\n\t}\n\tlock.Unlock()\n\tdefer func() {\n\t\tif closeErr := archiveFile.Close(); err == nil && closeErr != nil {\n\t\t\terr = fmt.Errorf(\"failed to close archive file %s: %w\", archivePath, closeErr)\n\t\t}\n\t}()\n\n\tlog := log.WithField(\"name\", archivePath)\n\tlog.Info(\"archiving\")\n\n\twrap, err := template.Apply(wrapFolder(arch))\n\tif err != nil {\n\t\treturn err\n\t}\n\ta, err := archive.New(archiveFile, format)\n\tif err != nil {\n\t\treturn err\n\t}\n\ta = NewEnhancedArchive(a, wrap)\n\tdefer func() {\n\t\tif closeErr := a.Close(); err == nil && closeErr != nil {\n\t\t\terr = fmt.Errorf(\"failed to close archive %s: %w\", archivePath, closeErr)","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/goreleaser/goreleaser/blob/f5edd7395693c0c6b501dc722d445d2e86af854d/internal/pipe/archive/archive.go#L181-L217","documentation":"After writing archive contents, goreleaser wraps the archive file Close() call; if closing fails (and no earlier error occurred) it rewrites the error with this message. Close failures indicate buffered data could not be fully flushed to disk.","triggerScenarios":"The underlying archive/archiveg writer returns an error on Close — typically ENOSPC while flushing the gzip/zip buffer, I/O error on the file descriptor, or an EnhancedArchive wrapper Close error.","commonSituations":"Disk filling up mid-release on CI runners; NFS/network filesystems dropping during large archives; file descriptor exhaustion (EMFILE) after many archives in one run.","solutions":["Free disk space and re-run with --clean","Archive to a local disk instead of a network mount for dist/","Check ulimit -n / file descriptor limits when archiving many artifacts","Re-run the release; transient I/O errors usually do not recur"],"exampleFix":"// before (CI)\nruns-on: macos-latest  # small disk, large archives\n// after (CI)\n# free space or pick a runner with more disk before running goreleaser","handlingStrategy":"retry","validationCode":"df -h . | awk 'NR==2 {print $4}'   # require adequate free space\nulimit -n   # check descriptor limits","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"failed to close archive\") {\n    // free disk space, then re-run the release\n    return retryRelease()\n}","preventionTips":["Keep dist/ on local disk, not NFS/network mounts","Monitor disk space in CI before large releases","Re-run transient I/O failures once before investigating"],"tags":["goreleaser","filesystem","disk-space","io"],"backgroundTag":"disk-full-write-failed","analyzedSha":"f5edd7395693c0c6b501dc722d445d2e86af854d","analyzedAt":"2026-09-05T09:57:18.807Z","contentChangedAt":"2026-09-05T09:57:18.807Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}