fatedier/frp · error

include: parse directory of %s failed: %v

Error message

include: parse directory of %s failed: %v

What it means

While resolving an includes[] entry, filepath.Abs on the file's directory failed and the OS error is appended. This is an environment-level failure (e.g. GetCurrentDirectory/MkdirAll-style OS error), distinct from a missing directory — the path could not even be made absolute.

Source

Thrown at pkg/config/v1/validation/client.go:182

		warnings = AppendError(warnings, checkTLSConfig("transport.tls.keyFile", c.TLS.KeyFile))
		warnings = AppendError(warnings, checkTLSConfig("transport.tls.trustedCaFile", c.TLS.TrustedCaFile))
	}

	if !slices.Contains(SupportedTransportProtocols, c.Protocol) {
		errs = AppendError(errs, fmt.Errorf("invalid transport.protocol, optional values are %v", SupportedTransportProtocols))
	}
	if !slices.Contains(SupportedWireProtocols, c.WireProtocol) {
		errs = AppendError(errs, fmt.Errorf("invalid transport.wireProtocol, optional values are %v", SupportedWireProtocols))
	}
	return warnings, errs
}

func validateIncludeFiles(files []string) (Warning, error) {
	var errs error
	for _, f := range files {
		absDir, err := filepath.Abs(filepath.Dir(f))
		if err != nil {
			errs = AppendError(errs, fmt.Errorf("include: parse directory of %s failed: %v", f, err))
			continue
		}
		if _, err := os.Stat(absDir); os.IsNotExist(err) {
			errs = AppendError(errs, fmt.Errorf("include: directory of %s not exist", f))
		}
	}
	return nil, errs
}

func ValidateAllClientConfig(
	c *v1.ClientCommonConfig,
	proxyCfgs []v1.ProxyConfigurer,
	visitorCfgs []v1.VisitorConfigurer,
	unsafeFeatures *security.UnsafeFeatures,
) (Warning, error) {
	validator := NewConfigValidator(unsafeFeatures)
	var warnings Warning
	if c != nil {

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Inspect the %s include entry and make it a clean absolute or sane relative path (e.g. "./conf.d/*.toml")
  2. Ensure the process working directory exists and is readable when using relative includes
  3. On Windows, prefer absolute paths (C:\frp\conf.d\*.toml) for includes

Example fix

# before
includes = [":", ""]

# after
includes = ["./conf.d/*.toml"]
Defensive patterns

Strategy: try-catch

Validate before calling

for _, inc := range cfg.Includes {
    if _, err := filepath.Abs(filepath.Dir(inc)); err != nil {
        // reject/fix the include entry before running frpc
    }
}

Try / catch

if _, err := validation.ValidateAllClientConfig(cc, proxies, visitors, uf); err != nil {
    if strings.Contains(err.Error(), "include: parse directory of") {
        // rewrite includes[] to clean absolute paths and re-run validation
    }
}

Prevention

When it happens

Trigger: includes = ["fragments/*.toml"] where filepath.Dir(f) yields something filepath.Abs cannot resolve — in practice rare on Linux, more plausible on Windows with invalid drive letters/UNC edge cases, or when the working directory has been deleted.

Common situations: Running frpc as a service whose cwd was removed; malformed include paths like "" or ":"; Windows path quirks with relative include entries.

Related errors


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