wagoodman/dive · error
unexpected tar file (XHeader): type=%v name=%s
Error message
unexpected tar file (XHeader): type=%v name=%s
What it means
This error is returned by dive's docker image archive parser when it encounters a tar entry whose typeflag is tar.TypeXHeader ('x'), a PAX extended header. PAX headers carry metadata (long paths, large UIDs/GIDs, sparse files, timestamps) that applies to the entry that follows it, and dive's parser has no handling for them, so it aborts the whole archive walk instead of skipping or merging the extension data.
Source
Thrown at dive/image/docker/image_archive.go:242
for {
header, err := tarReader.Next()
if err == io.EOF {
break
} else if err != nil {
return nil, err
}
// always ensure relative path notations are not parsed as part of the filename
name := path.Clean(header.Name)
if name == "." {
continue
}
switch header.Typeflag {
case tar.TypeXGlobalHeader:
return nil, fmt.Errorf("unexpected tar file: (XGlobalHeader): type=%v name=%s", header.Typeflag, name)
case tar.TypeXHeader:
return nil, fmt.Errorf("unexpected tar file (XHeader): type=%v name=%s", header.Typeflag, name)
default:
files = append(files, filetree.NewFileInfoFromTarHeader(tarReader, header, name))
}
}
return files, nil
}
func (img *ImageArchive) ToImage(id string) (*image.Image, error) {
trees := make([]*filetree.FileTree, 0)
// build the content tree
for _, treeName := range img.manifest.LayerTarPaths {
tr, exists := img.layerMap[treeName]
if exists {
trees = append(trees, tr)
continue
}
return nil, fmt.Errorf("could not find '%s' in parsed layers", treeName)View on GitHub (pinned to d6c691947f)
Solutions
- Re-export the image so layer tars use ustar/gnu format: 'docker save <image> -o img.tar' directly (do not untar/re-tar on macOS with default bsdtar settings)
- If re-tar locally, force a compatible format: 'tar --format=gnu -cf out.tar ...' (GNU tar) or 'COPYFILE_DISABLE=1 tar --format=ustar ...' on macOS
- Upgrade dive to a release that tolerates or skips PAX extension headers instead of erroring
- If you control the archive producer, emit POSIX ustar archives (no --format=pax, no --xattrs)
Example fix
# before (macOS bsdtar defaults can inject PAX headers) untar docker-save.tar && tar -cf rebuilt.tar . # may produce typeflag 'x' dive docker-save.tar # after (force gnu/ustar, drop extended headers) untar docker-save.tar && tar --format=gnu -cf rebuilt.tar . dive rebuilt.tar
Defensive patterns
Strategy: validation
Validate before calling
// Before loading, scan the archive for PAX extension headers and reject/pre-process it.
func hasPaxHeaders(r io.Reader) (bool, error) {
tr := tar.NewReader(r)
for {
hdr, err := tr.Next()
if err == io.EOF { return false, nil }
if err != nil { return false, err }
if hdr.Typeflag == tar.TypeXHeader || hdr.Typeflag == tar.TypeXGlobalHeader {
return true, nil
}
}
}
pax, err := hasPaxHeaders(bytes.NewReader(archiveBytes))
if err == nil && pax { /* re-pack with gnu format or reject with a clear message */ } Try / catch
// Go: treat as a returned error and branch on the message.
if _, err := docker.NewImageArchive(f); err != nil {
if strings.Contains(err.Error(), "unexpected tar file") {
// archive format problem: re-export with ustar/gnu format and retry once
}
return err
} Prevention
- Always consume the tar produced directly by 'docker save'/'podman image save' instead of re-tarring it
- When repacking layer tars, force '--format=gnu' or '--format=ustar' and disable xattrs/POSIX.1-2001 extensions
- Avoid macOS bsdtar defaults when touching docker-save archives; set COPYFILE_DISABLE=1 as well
When it happens
Trigger: Calling NewImageArchive (or any dive API that ingests a 'docker save' tar, e.g. podman resolver.Fetch -> resolveFromDockerArchive) on an archive containing PAX-format entries. This happens when the tar was produced by bsdtar (macOS default), by buildkit-built images exported with newer docker/podman versions, or by any tool that writes POSIX.1-2001 (pax) format tars.
Common situations: Running dive (or a tool embedding it) on an image saved on macOS where the layer tars were re-packed with PAX headers; images built with buildkit and saved with recent Docker/Podman releases; hand-modified or re-tarred image archives where the default tar format is pax.
Related errors
- unexpected tar file: (XGlobalHeader): type=%v name=%s
- could not find '%s' in parsed layers
- failed to unmarshal manifest: %w
- cannot export analysis: %w
- unable to determine image source from %q: %v
AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15).
Data as JSON: /api/errors/8cf30ac3df48be21.
Report an issue: GitHub.