vxcontrol/pentagi · error
failed to read tar header: %w
Error message
failed to read tar header: %w
What it means
After CopyFromContainer returns a tar stream, readFileFromContainer iterates it with tar.Reader.Next(). Any decode error that is not io.EOF — meaning the byte stream Docker returned is not a valid/truncated tar archive — is wrapped with this message. It indicates corruption between the daemon and the reader, not a problem with the file itself.
Source
Thrown at backend/pkg/tools/terminal.go:388
if !isRunning {
return "", fmt.Errorf("container runtime is not operational")
}
reader, stats, err := t.dockerClient.CopyFromContainer(ctx, containerName, path)
if err != nil {
return "", fmt.Errorf("failed to copy file: %w", err)
}
defer reader.Close()
var buffer strings.Builder
tarReader := tar.NewReader(reader)
for {
tarHeader, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return "", fmt.Errorf("failed to read tar header: %w", err)
}
if tarHeader.FileInfo().IsDir() {
continue
}
if stats.Mode.IsDir() {
buffer.WriteString("--------------------------------------------------\n")
buffer.WriteString(
fmt.Sprintf("'%s' file content (with size %d bytes) shown below:\n",
tarHeader.Name, tarHeader.Size,
),
)
}
const maxReadFileSize int64 = 100 * 1024 * 1024 // 100 MB limit
if tarHeader.Size > maxReadFileSize {
return "", fmt.Errorf("file '%s' size %d exceeds maximum allowed size %d", tarHeader.Name, tarHeader.Size, maxReadFileSize)View on GitHub (pinned to ea665308ba)
Solutions
- Retry the read — truncation is often transient; wrap the whole CopyFromContainer+tar loop in a retry with backoff
- Avoid tar-reading pseudo-filesystem entries; target regular files (check tarHeader.Typeflag / FileInfo().Mode())
- Check the Docker daemon logs and connectivity to the remote host for mid-stream disconnects
- If reading large files, read them in chunks or increase client timeouts rather than letting the stream die
Example fix
// before
_, err = tarReader.Read(fileContent)
// after
tarHeader, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
if errors.Is(err, io.ErrUnexpectedEOF) {
return "", fmt.Errorf("truncated tar stream from container %s, retry: %w", containerName, err)
}
return "", fmt.Errorf("failed to read tar header: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
// No pre-call validation possible; optionally verify daemon connectivity first:
if _, err := dockerClient.Ping(ctx); err != nil {
return fmt.Errorf("docker daemon unreachable, fix before reading: %w", err)
} Type guard
func isTruncatedTar(err error) bool {
return errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, tar.ErrHeader)
} Try / catch
var content string
var err error
for attempt := 0; attempt < 3; attempt++ {
content, err = tool.ReadFile(ctx, flowID, path)
if err == nil || !strings.Contains(err.Error(), "failed to read tar header") {
break
}
time.Sleep(time.Duration(1<<attempt) * 500 * time.Millisecond)
} Prevention
- Use stable local connections or reliable TLS to remote Docker hosts
- Avoid tar-reading /proc, /sys, sockets, and FIFOs
- Set generous client timeouts for large copies
- Retry transient stream errors with exponential backoff
When it happens
Trigger: The tar stream from CopyFromContainer was truncated (network hiccup to a remote Docker host, daemon killed mid-response), the reader was closed early, or a non-archive response was produced for special files (device/pipe entries the daemon cannot serialize).
Common situations: Reading from a container on a flaky remote Docker host (DOCKER_HOST over TCP/TLS); reading pseudo-files from /proc, /sys, or socket/fifo entries that don't tar cleanly; reading very large files over an unstable connection; a concurrent `docker cp`/container removal interrupted the stream.
Related errors
- failed to copy file: %w
- file '%s' has invalid size %d
- failed to read file '%s' content: %w
- tar archive header generation failed: %w
- tar archive content serialization failed: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/045ad939ca002f63.
Report an issue: GitHub.