twpayne/chezmoi · error

%s: unsupported file mode %o

Error message

%s: unsupported file mode %o

What it means

walkArchiveZip (internal/chezmoi/archive.go:335) maps zip entry file modes to archive entry types. When a zip entry's mode does not map to a recognized type (regular file, dir, symlink), it returns "%s: unsupported file mode %o" with the entry name and mode.

Source

Thrown at internal/chezmoi/archive.go:335

		case 0, fs.ModeDir, fs.ModeSymlink:
			// Create implicit parent directories.
			if dir, _ := relPath.Split(); !dir.IsEmpty() {
				dirComponents := dir.TrimTrailingSlash().SplitAll()
				for i := range dirComponents {
					implicitParentDirRelPath := NewRelPathFromComponents(dirComponents[:i+1]...)
					implicitParentDirFileInfo := implicitTarDirHeader(implicitParentDirRelPath, fileInfo.ModTime()).FileInfo()
					switch err := processHeader(implicitParentDirRelPath, implicitParentDirFileInfo); {
					case errors.Is(err, fs.SkipDir):
						continue FILE
					case errors.Is(err, fs.SkipAll):
						return nil
					case err != nil:
						return err
					}
				}
			}
		default:
			return fmt.Errorf("%s: unsupported file mode %o", zipFile.Name, fileInfo.Mode())
		}

		switch fileInfo.Mode() & fs.ModeType {
		case 0:
			zipFileReader, err := zipFile.Open()
			if err != nil {
				return err
			}
			err = f(relPath, fileInfo, zipFileReader, "")
			err2 := zipFileReader.Close()
			switch {
			case errors.Is(err, fs.SkipAll):
				return err2
			case err != nil:
				return err
			case err2 != nil:
				return err2
			}

View on GitHub (pinned to f901167e46)

Solutions

  1. Inspect the zip entries (`unzip -l`) and identify the offending entry; recreate the zip with standard tooling.
  2. Re-zip using `zip -r` or a mainstream tool so entries get standard modes.
  3. Convert the archive to tar format, which chezmoi handles more permissively.

Example fix

# before: zip created by unusual tool
weird-tool --archive=site.zip
# after
rm site.zip && zip -r site.zip ./myfiles/
Defensive patterns

Strategy: validation

Validate before calling

zr, err := zip.OpenReader(path)
if err != nil { return err }
for _, f := range zr.File {
    if f.Mode()&os.ModeType != 0 && !(f.Mode().IsDir() || f.Mode().IsRegular() || f.Mode()&os.ModeSymlink != 0) {
        return fmt.Errorf("unsupported zip entry mode: %s %o", f.Name, f.Mode())
    }
}

Try / catch

if err := walkArchiveZip(ra, fn); err != nil {
    if strings.Contains(err.Error(), "unsupported file mode") {
        // re-zip entries with standard tooling
    }
    return err
}

Prevention

When it happens

Trigger: Calling WalkArchive on a zip whose entries carry unusual mode bits (e.g. non-regular modes produced by nonstandard zip creators), or a zip with entries lacking a valid FileInfo mode.

Common situations: Zips produced by unusual tools or platforms that set exotic external attributes; zips mixing device-like or irregular mode bits; corrupted zip central directory.

Related errors


AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01). Data as JSON: /api/errors/33f43e3117dd11ef. Report an issue: GitHub.