owasp-amass/amass · error

failed to open resolvers file: %w

Error message

failed to open resolvers file: %w

What it means

loadResolversFromFile reads a text file of newline-separated resolver IPs and wraps any os.ReadFile failure with this message. It is thrown when the resolvers file cannot be opened/read (missing file, bad permissions, or a path error). The underlying OS error is preserved via %w so it can be inspected with errors.Is/As.

Source

Thrown at config/resolvers.go:226

	if len(resolverIPs) == 0 {
		return errors.New("no valid resolvers were found")
	}

	c.Resolvers = resolverIPs

	return nil
}

func (c *Config) loadResolversFromFile(path string) ([]string, error) {
	absPath, err := filepath.Abs(path)
	if err != nil {
		return nil, fmt.Errorf("failed to get absolute path: %v", err)
	}

	data, err := os.ReadFile(absPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open resolvers file: %w", err)
	}

	// Split the file data by newlines to get the IP addresses.
	lines := strings.Split(string(data), "\n")

	var resolvers []string
	for _, line := range lines {
		line = strings.TrimSpace(line)
		// Skip empty lines.
		if line == "" {
			continue
		}

		// Check if each line in the file is a valid IP address.
		ip := net.ParseIP(line)
		if ip == nil {
			return nil, fmt.Errorf("invalid IP address in resolvers file: %s", line)
		}

View on GitHub (pinned to 79299dce87)

Solutions

  1. Verify the resolvers file exists at the configured path (ls the path, check for typos)
  2. Fix file permissions so the process user can read it (chmod/chown)
  3. If the path is relative, confirm the working directory or switch to an absolute path
  4. Inspect the wrapped %w error (os.IsNotExist vs permission) to confirm which OS-level cause applies

Example fix

// before
cfg.LoadResolversFromFile("/etc/amass/reslover.txt") // typo
// after
cfg.LoadResolversFromFile("/etc/amass/resolvers.txt")
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(path); err != nil { return fmt.Errorf("resolvers file not accessible: %w", err) }

Type guard

func fileReadable(path string) bool { f, err := os.Open(path); if err != nil { return false }; f.Close(); return true }

Try / catch

res, err := loadResolversFromFile(p)
if err != nil {
    var perr *fs.PathError
    if errors.As(err, &perr) && os.IsNotExist(perr) { /* fix path */ }
    return err
}

Prevention

When it happens

Trigger: Config-loadResolversFromFile is called with a path that does not exist, points to a directory, or is unreadable (permission denied); loadResolverSettings passes the user-supplied resolvers file path from settings.

Common situations: Typo in the resolvers file path in the amass config; file deleted or moved after config was written; running in a container where the file was not mounted; insufficient read permissions on the file.

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 owasp-amass/amass@79299dce87 (2026-09-06). Data as JSON: /api/errors/9de06604a70635c0. Report an issue: GitHub.