shadow1ng/fscan · error

parser_read_hosts_failed: %w

Error message

parser_read_hosts_failed: %w

What it means

ParseIP reads target hosts from a file (the -hf flag). If ReadLinesFromFile fails to open or read the file, ParseIP wraps the error with the i18n message 'parser_read_hosts_failed'. It indicates the hosts file could not be loaded, not that any line was invalid (invalid lines are silently skipped).

Source

Thrown at common/parsers/parsers.go:41

- ReadLinesFromFile() - 文件读取
- ParseUserPassFile() - 用户密码对解析
- ParseHashFile()     - 哈希文件解析
*/

// =============================================================================
// IP/主机解析
// =============================================================================

// ParseIP 解析各种格式的IP地址
// 支持单个IP、IP范围、CIDR和文件输入
func ParseIP(host string, filename string, nohosts ...string) ([]string, error) {
	var hosts []string

	// 从文件读取主机列表
	if filename != "" {
		fileHosts, err := ReadLinesFromFile(filename)
		if err != nil {
			return nil, fmt.Errorf(i18n.GetText("parser_read_hosts_failed")+": %w", err)
		}
		for _, h := range fileHosts {
			parsed, err := parseHostString(h)
			if err != nil {
				continue // 跳过无效行
			}
			hosts = append(hosts, parsed...)
		}
	}

	// 解析主机参数
	if host != "" {
		hostList, err := parseHostString(host)
		if err != nil {
			return nil, fmt.Errorf(i18n.GetText("parser_parse_host_failed")+": %w", err)
		}
		hosts = append(hosts, hostList...)
	}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Check the file exists at the exact path (pwd/ls) and correct the path or run from the right directory
  2. Check file permissions (read access for the running user)
  3. If you don't need a hosts file, pass an empty filename and provide hosts via the host argument instead

Example fix

// before
hosts, err := parsers.ParseIP("", "./host.lst") // file moved
// after
hosts, err := parsers.ParseIP("", "/etc/fscan/hosts.txt") // absolute, existing path
Defensive patterns

Strategy: validation

Validate before calling

if fi, err := os.Stat(filename); err != nil || fi.IsDir() {
	return fmt.Errorf("hosts file unavailable: %s", filename)
}

Try / catch

hosts, err := parsers.ParseIP(h, hf)
if err != nil {
	var pathErr *os.PathError
	if errors.As(err, &pathErr) {
		log.Fatalf("cannot read hosts file %s: %v", pathErr.Path, pathErr.Err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling ParseIP(host, filename, ...) with a filename that does not exist, is a directory, or cannot be opened due to permissions — ReadLinesFromFile returns an error and this wrapper fires.

Common situations: Typo in the -hf path, running fscan from a different working directory so a relative path no longer resolves, or a hosts file with restrictive permissions.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/d4cede8ae0c1d799. Report an issue: GitHub.