{"record":{"id":"0633437ddef709cd","repo":"golang/go","slug":"archive-tar-missed-writing-d-bytes","errorCode":null,"errorMessage":"archive/tar: missed writing %d bytes","messagePattern":"archive/tar: missed writing (.+?) bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/archive/tar/writer.go","lineNumber":57,"sourceCode":"\ntype fileWriter interface {\n\tio.Writer\n\tfileState\n\n\tReadFrom(io.Reader) (int64, error)\n}\n\n// Flush finishes writing the current file's block padding.\n// The current file must be fully written before Flush can be called.\n//\n// This is unnecessary as the next call to [Writer.WriteHeader] or [Writer.Close]\n// will implicitly flush out the file's padding.\nfunc (tw *Writer) Flush() error {\n\tif tw.err != nil {\n\t\treturn tw.err\n\t}\n\tif nb := tw.curr.logicalRemaining(); nb > 0 {\n\t\treturn fmt.Errorf(\"archive/tar: missed writing %d bytes\", nb)\n\t}\n\tif _, tw.err = tw.w.Write(zeroBlock[:tw.pad]); tw.err != nil {\n\t\treturn tw.err\n\t}\n\ttw.pad = 0\n\treturn nil\n}\n\n// WriteHeader writes hdr and prepares to accept the file's contents.\n// The Header.Size determines how many bytes can be written for the next file.\n// If the current file is not fully written, then this returns an error.\n// This implicitly flushes any padding necessary before writing the header.\nfunc (tw *Writer) WriteHeader(hdr *Header) error {\n\tif err := tw.Flush(); err != nil {\n\t\treturn err\n\t}\n\ttw.hdr = *hdr // Shallow copy of Header\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/archive/tar/writer.go#L39-L75","documentation":"Returned by (*tar.Writer).Flush (writer.go:57) when the current file still has unwritten bytes — tw.curr.logicalRemaining() > 0. Flush is documented to require the current file be fully written first; calling it early (before writing Header.Size bytes) violates that contract.","triggerScenarios":"Calling Writer.Flush (or WriteHeader/Close, which call Flush implicitly) after WriteHeader with a declared Size but before writing exactly Size bytes of content. Also if the writer's content writer short-wrote or the caller stopped early.","commonSituations":"Declared header Size larger than the actual data streamed (e.g., set Size but io.Copy from a shorter reader); caller returns early from a walk without finishing the file; misuse of Flush as a generic sync point; mismatch between ContentLength and bytes written.","solutions":["Ensure you write exactly hdr.Size bytes after WriteHeader before calling Flush/WriteHeader/Close.","If the true size is unknown, stream to a buffer/counter first and set Size to the counted length.","Do not call Flush unless you specifically need block padding mid-stream; rely on WriteHeader/Close implicit flush.","If a write fails partway, abort the whole archive (the tar is already corrupt)."],"exampleFix":"// before\nhdr := &tar.Header{Name: \"f\", Size: 1024, Mode: 0644}\ntw.WriteHeader(hdr)\nio.CopyN(tw, src, 512) // only half\ntw.Flush() // -> missed writing 512 bytes\n\n// after\nhdr := &tar.Header{Name: \"f\", Size: 1024, Mode: 0644}\ntw.WriteHeader(hdr)\nio.Copy(tw, io.LimitReader(src, 1024)) // exactly Size\ntw.Flush()","handlingStrategy":"validation","validationCode":"// Count content before writing the header so Size is exact.\nfunc writeExact(tw *tar.Writer, name string, r io.Reader) error {\n    var buf bytes.Buffer\n    n, _ := io.Copy(&buf, r)\n    h := &tar.Header{Name: name, Mode: 0644, Size: int64(buf.Len())}\n    if err := tw.WriteHeader(h); err != nil {\n        return err\n    }\n    _, err := io.CopyN(tw, &buf, n)\n    return err\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write exactly Header.Size bytes before Flush/WriteHeader/Close.","When size is unknown, buffer-and-count first or use a streaming tar with deferred size patching.","Avoid calling Flush directly; rely on implicit flush by WriteHeader/Close."],"tags":["archive","tar","writer","flush","contract"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}