AlistGo/alist · error · ErrArchiveIllegalPath

ErrArchiveIllegalPath

ErrArchiveIllegalPath

Error message

archive entry has illegal path: %s

What it means

Per-entry guard in internal/archive/rardecode/utils.go decompress(): after handling directory headers, any RAR entry whose header.Mode() is not regular (symlink/device/FIFO) fails with ErrArchiveIllegalPath before the output file is created with O_EXCL.

Source

Thrown at internal/archive/rardecode/utils.go:189

	}
	opts := []rardecode.Option{fsOpt}
	if password != "" {
		opts = append(opts, rardecode.Password(password))
	}
	rc, err := rardecode.OpenReader(fileName, opts...)
	if err != nil {
		return nil, filterPassword(err)
	}
	ss[0].Closers.Add(rc)
	return &rc.Reader, nil
}

func decompress(reader *rardecode.Reader, header *rardecode.FileHeader, dstPath string, limiter *tool.SizeLimiter) error {
	if header.IsDir {
		return os.MkdirAll(dstPath, 0700)
	}
	if !header.Mode().IsRegular() {
		return fmt.Errorf("%w: %s", tool.ErrArchiveIllegalPath, header.Name)
	}
	if err := os.MkdirAll(filepath.Dir(dstPath), 0700); err != nil {
		return err
	}
	return _decompress(reader, header, dstPath, func(_ float64) {}, limiter)
}

func _decompress(reader *rardecode.Reader, header *rardecode.FileHeader, dstPath string, up model.UpdateProgress, limiter *tool.SizeLimiter) error {
	f, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
	if err != nil {
		return err
	}
	defer func() { _ = f.Close() }()
	_, err = io.Copy(limiter.WrapWriter(f), &stream.ReaderUpdatingProgress{
		Reader: &stream.SimpleReaderWithSize{
			Reader: reader,
			Size:   header.UnPackedSize,
		},

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Extract with a native RAR tool if special entries must be preserved
  2. Repack without special entries
  3. Verify the rar with 'rar t' / 'unrar t' to rule out corruption
Defensive patterns

Strategy: validation

Type guard

func rarHeaderSafe(h *rardecode.FileHeader) bool {
    return h.IsDir || h.Mode().IsRegular()
}

Try / catch

if err := decompress(reader, header, dstPath, limiter); err != nil {
    if errors.Is(err, tool.ErrArchiveIllegalPath) {
        return fmt.Errorf("unsafe rar member %q: %w", header.Name, err)
    }
    return err
}

Prevention

When it happens

Trigger: Single-file or nested extraction of a RAR entry that is a symlink or other special type — the final copy step re-checks the mode the rardecode library reported for the header.

Common situations: Same as the rardecode walker guard: Linux-flavored rars with links; corrupted headers misreporting modes.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/fafbdcdc37a1eebc. Report an issue: GitHub.