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)
			continue

View on GitHub (pinned to d6c691947f)

Solutions

  1. Update dive - later releases skip or handle XGlobalHeader/XHeader entries instead of failing
  2. Repack the layer tars in a tolerated format: extract and re-tar with --format=gnu (or ustar), then rebuild the archive
  3. 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)
  4. 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

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


AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15). Data as JSON: /api/errors/13bececbc681f034. Report an issue: GitHub.