{"record":{"id":"bc916e860f2b1a11","repo":"fatedier/frp","slug":"include-directory-of-s-not-exist-bc916e","errorCode":null,"errorMessage":"include: directory of %s not exist","messagePattern":"include: directory of (.+?) not exist","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/v1/validation/client.go","lineNumber":186,"sourceCode":"\tif !slices.Contains(SupportedTransportProtocols, c.Protocol) {\n\t\terrs = AppendError(errs, fmt.Errorf(\"invalid transport.protocol, optional values are %v\", SupportedTransportProtocols))\n\t}\n\tif !slices.Contains(SupportedWireProtocols, c.WireProtocol) {\n\t\terrs = AppendError(errs, fmt.Errorf(\"invalid transport.wireProtocol, optional values are %v\", SupportedWireProtocols))\n\t}\n\treturn warnings, errs\n}\n\nfunc validateIncludeFiles(files []string) (Warning, error) {\n\tvar errs error\n\tfor _, f := range files {\n\t\tabsDir, err := filepath.Abs(filepath.Dir(f))\n\t\tif err != nil {\n\t\t\terrs = AppendError(errs, fmt.Errorf(\"include: parse directory of %s failed: %v\", f, err))\n\t\t\tcontinue\n\t\t}\n\t\tif _, err := os.Stat(absDir); os.IsNotExist(err) {\n\t\t\terrs = AppendError(errs, fmt.Errorf(\"include: directory of %s not exist\", f))\n\t\t}\n\t}\n\treturn nil, errs\n}\n\nfunc ValidateAllClientConfig(\n\tc *v1.ClientCommonConfig,\n\tproxyCfgs []v1.ProxyConfigurer,\n\tvisitorCfgs []v1.VisitorConfigurer,\n\tunsafeFeatures *security.UnsafeFeatures,\n) (Warning, error) {\n\tvalidator := NewConfigValidator(unsafeFeatures)\n\tvar warnings Warning\n\tif c != nil {\n\t\twarning, err := validator.ValidateClientCommonConfig(c)\n\t\twarnings = AppendError(warnings, warning)\n\t\tif err != nil {\n\t\t\treturn warnings, err","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/v1/validation/client.go#L168-L204","documentation":"An includes[] entry points at a directory that does not exist on disk (os.Stat returns IsNotExist). frp validates include directories up front so a typo'd glob silently matching nothing can't hide configuration that the user believes is loaded.","triggerScenarios":"includes = [\"/etc/frpc/conf.d/*.toml\"] when /etc/frpc/conf.d hasn't been created; deploying frpc to a new host without provisioning the include directory; wrong relative base (cwd-dependent paths).","commonSituations":"Packaging/deployment scripts that forget to create the conf.d directory; running frpc from a different directory than intended so relative includes resolve elsewhere; renaming directories without updating includes.","solutions":["mkdir -p the directory named in the error message","Fix the path in includes[] (absolute paths are safest for services)","If includes are optional by design, guard by creating the directory in your deploy script/systemd ExecStartPre"],"exampleFix":"# before\nincludes = [\"/etc/frpc/conf.d/*.toml\"]  # dir absent\n# shell:\n# mkdir -p /etc/frpc/conf.d\n\n# after\nincludes = [\"/etc/frpc/conf.d/*.toml\"]  # dir exists","handlingStrategy":"validation","validationCode":"for _, inc := range cfg.Includes {\n    dir := filepath.Dir(inc)\n    if _, err := os.Stat(dir); os.IsNotExist(err) {\n        // provision the directory or drop the include before starting frpc\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["systemd ExecStartPre=/usr/bin/mkdir -p /etc/frpc/conf.d","Provision include directories in the same deploy step that writes configs"],"tags":["frp","config","includes","filesystem","deployment","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}