{"record":{"id":"db734a7df22e01ac","repo":"golang/go","slug":"file-larger-than-size-reported-by-stat","errorCode":null,"errorMessage":"file larger than size reported by stat","messagePattern":"file larger than size reported by stat","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/work/gc.go","lineNumber":525,"sourceCode":"\t\t\treturn err\n\t\t}\n\t\t// Note: Not using %-16.16s format because we care\n\t\t// about bytes, not runes.\n\t\tname := fi.Name()\n\t\tif len(name) > 16 {\n\t\t\tname = name[:16]\n\t\t} else {\n\t\t\tname += strings.Repeat(\" \", 16-len(name))\n\t\t}\n\t\tsize := fi.Size()\n\t\tfmt.Fprintf(w, \"%s%-12d%-6d%-6d%-8o%-10d`\\n\",\n\t\t\tname, 0, 0, 0, 0644, size)\n\t\tn, err := io.Copy(w, src)\n\t\tsrc.Close()\n\t\tif err == nil && n < size {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t} else if err == nil && n > size {\n\t\t\terr = fmt.Errorf(\"file larger than size reported by stat\")\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"copying %s to %s: %v\", ofile, afile, err)\n\t\t}\n\t\tif size&1 != 0 {\n\t\t\tw.WriteByte(0)\n\t\t}\n\t}\n\n\tif err := w.Flush(); err != nil {\n\t\treturn err\n\t}\n\treturn dst.Close()\n}\n\n// setextld sets the appropriate linker flags for the specified compiler.\nfunc setextld(ldflags []string, compiler []string) ([]string, error) {\n\tfor _, f := range ldflags {","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/work/gc.go#L507-L543","documentation":"While assembling an ar-format archive of object files, the go command writes each file preceded by a header whose size field comes from a prior stat. After io.Copy it checks the copied byte count against that size; if more bytes were read than stat reported (n > size), the file grew between stat and read - a race where the object file was modified concurrently.","triggerScenarios":"Fires in the archive-assembly code of gc.go when io.Copy returns n > size, where size = fi.Size() from the earlier os.Stat on the object file.","commonSituations":"A code generator or concurrent go build writing the object file mid-archive, a FUSE filesystem with inconsistent stat/read, or a network filesystem with caching lag.","solutions":["Ensure no concurrent process modifies object files during a go build","Re-run the build - transient races often do not recur","Move the build to a local filesystem if using NFS/FUSE"],"exampleFix":"// before (generator races with go build)\ngo generate & go build\n// after (sequential)\ngo generate && go build","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// A transient race: retry the build once\nif bytes.Contains(out, []byte(\"file larger than size reported by stat\")) {\n    out, err = cmd.CombinedOutput()\n}","preventionTips":["Never run generators or concurrent builds that write the same object files","Build on a local filesystem, not NFS/FUSE","Sequence `go generate` before `go build` rather than in parallel"],"tags":["go-toolchain","archive","race-condition","filesystem"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}