owasp-amass/amass · error

failed to open the log file: %v

Error message

failed to open the log file: %v

What it means

NewFileLogger failed at os.OpenFile on filepath.Join(dir, logfile) with append/create/write flags: commonly a permission error on the target path, a path that is a directory, or an unusable log directory (the dir itself was just created with MkdirAll, so that step succeeded). The os error is wrapped with %v, losing errors.Is matching.

Source

Thrown at internal/tools/log.go:49

	}

	return errors.New("logger handler is not enabled")
}

func NewFileLogger(dir, logfile string) (*slog.Logger, error) {
	if logfile == "" {
		return nil, fmt.Errorf("no log file specified")
	}

	if dir != "" {
		if err := os.MkdirAll(dir, 0640); err != nil {
			return nil, fmt.Errorf("failed to create the log directory: %v", err)
		}
	}

	f, err := os.OpenFile(filepath.Join(dir, logfile), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return nil, fmt.Errorf("failed to open the log file: %v", err)
	}

	return slog.New(slog.NewJSONHandler(f, nil)), nil
}

func NewSyslogLogger() (*slog.Logger, error) {
	port := os.Getenv("SYSLOG_PORT")
	host := strings.ToLower(os.Getenv("SYSLOG_HOST"))
	transport := strings.ToLower(os.Getenv("SYSLOG_TRANSPORT"))

	if host == "" {
		return nil, fmt.Errorf("no syslog host specified")
	}
	if port == "" {
		port = "514"
	}
	if transport == "" {
		transport = "udp"

View on GitHub (pinned to 79299dce87)

Solutions

  1. Check the exact target path (filepath.Join(dir, logfile)) with ls -ld and fix ownership/permissions or pick another path
  2. Ensure the target is not a directory and remove/rename it if so
  3. Run the process as a user with write access to the directory, or pre-create the log file with suitable mode
  4. Review audit logs (SELinux AVC / AppArmor) if permissions look correct but opening still fails

Example fix

// before
f, _ := os.OpenFile("/var/log/amass.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) // EACCES
// after
sudo touch /var/log/amass.log && sudo chown $USER /var/log/amass.log
// or use a user-writable path: os.OpenFile(filepath.Join(home, "amass.log"), ...)
Defensive patterns

Strategy: try-catch

Validate before calling

target := filepath.Join(dir, logfile)
if st, err := os.Stat(target); err == nil && st.IsDir() {
	return fmt.Errorf("log path %s is a directory", target)
}
if dir != "" {
	probe := filepath.Join(dir, ".wtest")
	if err := os.WriteFile(probe, nil, 0600); err != nil {
		return fmt.Errorf("log dir not writable: %v", err)
	}
	os.Remove(probe)
}

Try / catch

logger, err := tools.NewFileLogger(dir, logfile)
if err != nil {
	if strings.Contains(err.Error(), "failed to open the log file") {
		// fall back to stderr logging
		logger = slog.New(slog.NewJSONHandler(os.Stderr, nil))
	} else { return err }
}

Prevention

When it happens

Trigger: The joined path (dir/logfile) is unwritable, the path exists as a directory, the file is owned by another user without group write, the path exceeds NAME_MAX, or O_NOFOLLOW-style symlinks/permission issues (e.g. sticky /tmp misuse).

Common situations: Rotated log file replaced by a root-owned file; log file name accidentally equal to an existing directory; writing into /var/log without privileges; SELinux/AppArmor denials in hardened environments.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of owasp-amass/amass@79299dce87 (2026-09-06). Data as JSON: /api/errors/5dd74dadbe646dc9. Report an issue: GitHub.