golang/go · error
tar: cannot add non-regular file
Error message
tar: cannot add non-regular file
What it means
Returned by Writer.AddFS when walking an fs.FS and encountering a directory entry whose type is neither regular, directory, nor symlink. AddFS intentionally supports only those three kinds (the portable subset); device files, sockets, named pipes, and other special files are refused because they cannot be represented portably in a tar that will be extracted on arbitrary platforms.
Source
Thrown at src/archive/tar/writer.go:426
if err != nil {
return err
}
if name == "." {
return nil
}
info, err := d.Info()
if err != nil {
return err
}
linkTarget := ""
if typ := d.Type(); typ == fs.ModeSymlink {
var err error
linkTarget, err = fs.ReadLink(fsys, name)
if err != nil {
return err
}
} else if !typ.IsRegular() && typ != fs.ModeDir {
return errors.New("tar: cannot add non-regular file")
}
h, err := FileInfoHeader(info, linkTarget)
if err != nil {
return err
}
h.Name = name
if d.IsDir() {
h.Name += "/"
}
if err := tw.WriteHeader(h); err != nil {
return err
}
if !d.Type().IsRegular() {
return nil
}
f, err := fsys.Open(name)
if err != nil {
return errView on GitHub (pinned to b6b368adc5)
Solutions
- Pre-filter the fs.FS so AddFS only sees regular files, directories, and symlinks — wrap with an fs.FS that skips other types.
- Use fs.WalkDir yourself and skip entries where !d.Type().IsRegular() && d.Type() != fs.ModeDir && d.Type() != fs.ModeSymlink.
- Stage the content into a clean directory (cp -r without special files) before archiving.
- If you must archive special files, write those headers manually with FileInfoHeader (TypeChar/TypeBlock/TypeFifo) — sockets are still unsupported.
Example fix
// before
tw := tar.NewWriter(w)
err := tw.AddFS(os.DirFS("/var/run")) // contains sockets -> throws
// after
tw := tar.NewWriter(w)
err := fs.WalkDir(os.DirFS("src"), ".", func(name string, d fs.DirEntry, err error) error {
if err != nil { return err }
t := d.Type()
if !t.IsRegular() && t != fs.ModeDir && t != fs.ModeSymlink {
return nil // skip sockets, pipes, devices
}
// ... FileInfoHeader + WriteHeader + Copy as in AddFS
return nil
}) Defensive patterns
Strategy: validation
Validate before calling
err := fs.WalkDir(fsys, ".", func(name string, d fs.DirEntry, err error) error {
if err != nil { return err }
t := d.Type()
if !t.IsRegular() && t != fs.ModeDir && t != fs.ModeSymlink {
return nil // skip sockets, pipes, devices
}
return nil
}) Type guard
func isArchivable(t fs.FileMode) bool {
return t.IsRegular() || t == fs.ModeDir || t == fs.ModeSymlink
} Try / catch
if err := tw.AddFS(fsys); err != nil && strings.Contains(err.Error(), "cannot add non-regular file") {
log.Printf("skipping non-regular files in %v", fsys)
err = nil
} Prevention
- Pre-filter the fs.FS so AddFS only sees regular files, dirs, and symlinks.
- Avoid passing os.DirFS of system directories (/var/run, /tmp) that contain sockets.
- Stage content into a clean directory before archiving.
When it happens
Trigger: Calling tw.AddFS(fsys) where fsys contains a Unix socket, named pipe (FIFO), character/block device, or any other non-regular non-directory non-symlink entry.
Common situations: Archiving a project directory that contains a .git/objects/pack/*.idx socket-like artifact, a docker socket bind-mounted into the tree, a node_modules with FIFOs, or /tmp-like filesystems with sockets; archiving a real OS filesystem (os.DirFS) rather than a clean file tree.
Related errors
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/0006055b6a0ed0a5.
Report an issue: GitHub.