fatedier/frp · error

include: parse directory of %s failed: %v

Error message

include: parse directory of %s failed: %v

What it means

While validating the legacy frpc INI [common] section, frp calls filepath.Abs on the directory of each entry in includes. If the OS cannot produce an absolute path for that directory, this error is returned wrapping the underlying syscall error. This is a low-level filesystem failure, not a config-logic mistake.

Source

Thrown at pkg/config/legacy/client.go:390

		}

		if cfg.TLSKeyFile != "" {
			fmt.Println("WARNING! tls_key_file is invalid when tls_enable is false")
		}

		if cfg.TLSTrustedCaFile != "" {
			fmt.Println("WARNING! tls_trusted_ca_file is invalid when tls_enable is false")
		}
	}

	if !slices.Contains([]string{"tcp", "kcp", "quic", "websocket", "wss"}, cfg.Protocol) {
		return fmt.Errorf("invalid protocol")
	}

	for _, f := range cfg.IncludeConfigFiles {
		absDir, err := filepath.Abs(filepath.Dir(f))
		if err != nil {
			return fmt.Errorf("include: parse directory of %s failed: %v", f, err)
		}
		if _, err := os.Stat(absDir); os.IsNotExist(err) {
			return fmt.Errorf("include: directory of %s not exist", f)
		}
	}
	return nil
}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Use absolute paths for every entry in includes
  2. Ensure the process working directory exists and is readable when frpc starts (restart frpc from a valid cwd)
  3. If the directory genuinely exists, check dmesic/syscall-level errors (permissions, I/O) on the host

Example fix

# before
includes = ./conf/*.ini

# after
includes = /etc/frp/conf/*.ini
Defensive patterns

Strategy: validation

Validate before calling

for _, f := range includeGlobs {
    dir := filepath.Dir(f)
    if !filepath.IsAbs(dir) {
        dir, _ = filepath.Abs(dir) // force resolution early
    }
    if dir == "" { return fmt.Errorf("cannot resolve directory of %s", f) }
}

Try / catch

err := cfg.Validate()
if err != nil && strings.Contains(err.Error(), "include: parse directory") { /* log and re-check cwd availability; restart process from valid cwd */ }

Prevention

When it happens

Trigger: includes entries whose directory path cannot be resolved by filepath.Abs — in practice rare: it fails when os.Getwd() errors (e.g. the working directory was deleted while frpc runs) combined with a relative include path, or on platforms where path resolution returns an error.

Common situations: frpc started from a directory that is later deleted/replaced (CI scratch dirs, container overlay churn) while using relative includes; extremely uncommon in normal deployments.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/85d2aa9abf09689d. Report an issue: GitHub.