{"record":{"id":"59b606524018cf38","repo":"k3s-io/k3s","slug":"tar-error-v","errorCode":null,"errorMessage":"tar error: %v","messagePattern":"tar error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/untar/untar.go","lineNumber":56,"sourceCode":"\t\tif err != nil {\n\t\t\tlogrus.Printf(\"error extracting tarball into %s after %d files, %d dirs, %v: %v\", dir, nFiles, len(madeDir), td, err)\n\t\t}\n\t}()\n\tzr, err := zstd.NewReader(r, zstd.WithDecoderMaxMemory(tarfile.MaxDecoderMemory))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error extracting zstd-compressed body: %v\", err)\n\t}\n\tdefer zr.Close()\n\ttr := tar.NewReader(zr)\n\tloggedChtimesError := false\n\tfor {\n\t\tf, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tlogrus.Printf(\"tar reading error: %v\", err)\n\t\t\treturn fmt.Errorf(\"tar error: %v\", err)\n\t\t}\n\t\tif !validRelPath(f.Name) {\n\t\t\treturn fmt.Errorf(\"tar contained invalid name error %q\", f.Name)\n\t\t}\n\t\trel := filepath.FromSlash(f.Name)\n\t\tabs := filepath.Join(dir, rel)\n\n\t\tfi := f.FileInfo()\n\t\tmode := fi.Mode()\n\t\tswitch {\n\t\tcase mode.IsRegular():\n\t\t\t// Make the directory. This is redundant because it should\n\t\t\t// already be made by a directory entry in the tar\n\t\t\t// beforehand. Thus, don't check for errors; the next\n\t\t\t// write will fail with the same error.\n\t\t\tdir := filepath.Dir(abs)\n\t\t\tif !madeDir[dir] {\n\t\t\t\tif err := os.MkdirAll(filepath.Dir(abs), 0755); err != nil {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/untar/untar.go#L38-L74","documentation":"After the zstd stream is opened, untar iterates tar entries; any error from tar.Reader.Next other than io.EOF (corrupt tar structure, truncated archive mid-entry, checksum mismatch in the stream) is logged as 'tar reading error' and returned wrapped as 'tar error'. Like the zstd error above, this occurs while extracting the embedded data-dir payload during first boot or upgrade.","triggerScenarios":"untar's tr.Next() fails mid-iteration: the embedded tarball is truncated (binary cut short), an entry header is corrupt, or the underlying reader errors partway. The deferred log line reports how many files/directories were extracted before the failure, localizing the truncation point.","commonSituations":"Partially downloaded or corrupted k3s binaries (most common); disk filling up while writing extracted files can surface as reader/writer errors here; binaries repacked or stripped in ways that damaged the embedded blob.","solutions":["Re-download the k3s binary and verify its sha256 checksum against the official checksums file.","Check free disk space and dmesg for filesystem errors on the data-dir volume; free space and retry.","Remove leftover '<dir>-tmp' extraction directories (they are auto-removed, but verify) and restart k3s to re-extract cleanly.","If self-built, rebuild ensuring the embedded tarball asset is generated and embedded intact."],"exampleFix":"# before: truncated binary\nls -l k3s  # size smaller than published\n./k3s server  # tar error: unexpected EOF\n\n# after\nsha256sum -c sha256sums.txt && ./k3s server","handlingStrategy":"validation","validationCode":"// Same pre-flight as 198: binary checksum plus free-space check on data dir\nif !checksumMatches(\"k3s\", wantSHA) { log.Fatal(\"redownload k3s\") }\nif free, _ := diskFree(dataDir); free < minSpace { log.Fatal(\"insufficient disk for extraction\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify sha256 of downloaded binaries before deployment","Monitor disk space on the data-dir volume","Treat any 'tar error' at startup as corruption - replace the binary rather than retrying in place"],"tags":["tar","startup","integrity","filesystem"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}