wagoodman/dive · error
unexpected tar file: (XGlobalHeader): type=%v name=%s
Error message
unexpected tar file: (XGlobalHeader): type=%v name=%s
What it means
Returned while reading a layer tar (dive/image/docker/image_archive.go:240) when an entry has tar.Typeflag == tar.TypeXGlobalHeader (PAX global extended header). This dive version treats both global ('g') and per-file ('x') PAX extended headers as unexpected and refuses the layer outright. PAX headers are legal tar, so this is a format limitation, not a corrupt archive.
Source
Thrown at dive/image/docker/image_archive.go:240
var files []filetree.FileInfo
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)
continueView on GitHub (pinned to d6c691947f)
Solutions
- Update dive - later releases skip or handle XGlobalHeader/XHeader entries instead of failing
- Repack the layer tars in a tolerated format: extract and re-tar with --format=gnu (or ustar), then rebuild the archive
- Rebuild the image with a builder setting that avoids PAX global headers (e.g. DOCKER_BUILDKIT=0 legacy builder, or tar --format=gnu in your image pipeline)
- Confirm which entry trips it: tar -tvf <layer>.tar | head and look for pax_global_header
Example fix
# before (posix-format layer tar) tar --format=posix -cf layer.tar -C rootfs . # -> dive: unexpected tar file: (XGlobalHeader) # after tar --format=gnu -cf layer.tar -C rootfs . # (or simply upgrade dive, which skips global headers)
Defensive patterns
Strategy: fallback
Validate before calling
// detect PAX global headers in layer tars before dive rejects them
func layerTarsAreSafe(imageTar string) error {
for _, layerTar := range layerTarPathsIn(imageTar) {
f, err := os.Open(layerTar)
if err != nil {
return err
}
tr := tar.NewReader(f)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
if hdr.Typeflag == tar.TypeXGlobalHeader || hdr.Typeflag == tar.TypeXHeader {
return fmt.Errorf("%s contains PAX extended headers", layerTar)
}
}
f.Close()
}
return nil
} Try / catch
_, pathErrs, err := analysis.Run(img) // layer processing surfaces this error
if err != nil && strings.Contains(err.Error(), "unexpected tar file") {
// fallback: repack offending layers with GNU format and retry
if rerr := repackLayersAsGnu(imgTarPath); rerr == nil {
_, pathErrs, err = analysis.Run(reloadedImg) // retry once
}
}
if err != nil {
return err
} Prevention
- Upgrade dive - newer builds tolerate PAX headers
- Pin image-building tooling to tar formats dive accepts (gnu/ustar)
- Add a dive CI step early so format regressions from builder updates surface fast
When it happens
Trigger: Analyzing images whose layer tars were packed in POSIX/PAX format - GNU tar with --format=posix, buildkit/buildx stages emitting global headers, or build tools (some kaniko/nix/nerdctl paths) that write a pax_global_header entry.
Common situations: Images built with newer BuildKit versions or custom base-image pipelines suddenly failing dive CI though docker/podman handle them fine; reproducible-build setups that force POSIX tar format.
Related errors
- unexpected tar file (XHeader): type=%v name=%s
- cannot analyze image: %w
- cannot add relative path '%s'
- unable to extract from image '%s': %+v
- could not find image manifest
AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15).
Data as JSON: /api/errors/13bececbc681f034.
Report an issue: GitHub.