{"record":{"id":"ed52bab2e5275b61","repo":"golang/go","slug":"errwritehole","errorCode":"errWriteHole","errorMessage":"archive/tar: write non-NUL byte in sparse hole","messagePattern":"archive/tar: write non-NUL byte in sparse hole","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/archive/tar/common.go","lineNumber":41,"sourceCode":"\t\"strings\"\n\t\"time\"\n)\n\n// BUG: Use of the Uid and Gid fields in Header could overflow on 32-bit\n// architectures. If a large value is encountered when decoding, the result\n// stored in Header will be the truncated version.\n\nvar tarinsecurepath = godebug.New(\"tarinsecurepath\")\n\nvar (\n\tErrHeader          = errors.New(\"archive/tar: invalid tar header\")\n\tErrWriteTooLong    = errors.New(\"archive/tar: write too long\")\n\tErrFieldTooLong    = errors.New(\"archive/tar: header field too long\")\n\tErrWriteAfterClose = errors.New(\"archive/tar: write after close\")\n\tErrInsecurePath    = errors.New(\"archive/tar: insecure file path\")\n\terrMissData        = errors.New(\"archive/tar: sparse file references non-existent data\")\n\terrUnrefData       = errors.New(\"archive/tar: sparse file contains unreferenced data\")\n\terrWriteHole       = errors.New(\"archive/tar: write non-NUL byte in sparse hole\")\n\terrSparseTooLong   = errors.New(\"archive/tar: sparse map too long\")\n)\n\ntype headerError []string\n\nfunc (he headerError) Error() string {\n\tconst prefix = \"archive/tar: cannot encode header\"\n\tvar ss []string\n\tfor _, s := range he {\n\t\tif s != \"\" {\n\t\t\tss = append(ss, s)\n\t\t}\n\t}\n\tif len(ss) == 0 {\n\t\treturn prefix\n\t}\n\treturn fmt.Sprintf(\"%s: %v\", prefix, strings.Join(ss, \"; and \"))\n}","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/archive/tar/common.go#L23-L59","documentation":"errWriteHole (unexported) is returned by the writer when a non-NUL byte is written into a sparse hole region. Sparse holes are stored as zero gaps; writing real data there is a logic error because the hole has no allocated dense bytes. The zeroWriter only accepts NUL (0x00) bytes and rejects anything else.","triggerScenarios":"Calling Write on a tar entry that has sparse holes, and pushing a buffer that overlaps a hole region with non-zero bytes; mis-sequencing writes so data lands at an offset the sparse map designates as a hole.","commonSituations":"Manually writing a sparse file without aligning writes to the declared fragment offsets; buggy code that interleaves data and padding without zeroing the padding; using io.Copy into a sparse-aware writer when the source contains unexpected non-zero bytes in what should be holes.","solutions":["Align writes with the sparse map: write only into declared data fragments, and write NUL bytes (or nothing) into holes.","When you have a fully materialized file, do not declare sparse holes at all — use a normal regular file header.","Pre-zero any buffer used for padding: bytes.Fill(buf, 0) before writing it into hole regions.","If you genuinely need to write data where a hole was, fix the Sparses map first so the region becomes a data fragment."],"exampleFix":"// before\nhdr := &tar.Header{Size: 10, Sparses: []tar.SparseEntry{{Offset: 5, NumBytes: 5}}}\ntw.WriteHeader(hdr)\ntw.Write([]byte(\"abcdefghij\")) // bytes 0-4 are a hole, throws errWriteHole\n\n// after\nhdr := &tar.Header{Size: 10, Sparses: []tar.SparseEntry{{Offset: 5, NumBytes: 5}}}\ntw.WriteHeader(hdr)\ntw.Write(bytes.Repeat([]byte{0}, 5)) // hole region, NUL ok\ntw.Write([]byte(\"fghij\"))           // data fragment","handlingStrategy":"validation","validationCode":"// Before writing, ensure your buffer offsets align with sparse data fragments,\n// and that any hole-region bytes are zero.\nfor _, b := range buf {\n  if b != 0 { /* writing into a hole: re-check sparse map */ }\n}","typeGuard":"func isAllZero(b []byte) bool { for _, x := range b { if x != 0 { return false } }; return true }","tryCatchPattern":null,"preventionTips":["Align writes precisely with the sparse data fragments; never write data into hole regions.","Pre-zero any padding buffers before writing them.","Prefer non-sparse headers unless you genuinely have holes."],"tags":["archive-tar","sparse","writer","validation","data-integrity"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}