{"record":{"id":"d06832e864dd907e","repo":"fatedier/frp","slug":"render-extra-config-s-error-v","errorCode":null,"errorMessage":"render extra config %s error: %v","messagePattern":"render extra config (.+?) error: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/legacy/parse.go","lineNumber":90,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif _, err := os.Stat(absDir); os.IsNotExist(err) {\n\t\t\treturn nil, err\n\t\t}\n\t\tfiles, err := os.ReadDir(absDir)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, fi := range files {\n\t\t\tif fi.IsDir() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tabsFile := filepath.Join(absDir, fi.Name())\n\t\t\tif matched, _ := filepath.Match(filepath.Join(absDir, filepath.Base(path)), absFile); matched {\n\t\t\t\ttmpContent, err := GetRenderedConfFromFile(absFile)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"render extra config %s error: %v\", absFile, err)\n\t\t\t\t}\n\t\t\t\tout.Write(tmpContent)\n\t\t\t\tout.WriteString(\"\\n\")\n\t\t\t}\n\t\t}\n\t}\n\treturn out.Bytes(), nil\n}\n","sourceCodeStart":72,"sourceCodeEnd":99,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/legacy/parse.go#L72-L99","documentation":"While expanding includes for legacy INI configs, each matched file goes through GetRenderedConfFromFile (Go text/template rendering with environment values). If reading or rendering one file fails, frp returns 'render extra config <absFile> error: <cause>' naming the exact file. The inner error distinguishes template parse errors from execution errors.","triggerScenarios":"An included INI fragment contains invalid Go template syntax (unclosed {{, bad function), references undefined template funcs, or the file becomes unreadable (permissions, deleted mid-scan). The file must match the includes glob to be processed.","commonSituations":"Operators templating per-host values into included fragments ({{ .Envs.HOST }}) and introducing a typo; included files written by other tools with braces that collide with template delimiters; permission changes under different service users.","solutions":["Open the named absFile and fix the template syntax (usually an unclosed {{ }} or misspelled .Envs key)","Escape literal braces with {{\"{{\"}} where templates are not intended","Ensure the frpc process user can read the file, then re-run frpc verify"],"exampleFix":"# before (/etc/frp/conf/web.ini)\nserver_port = {{ .Envs.SERVER_PRT }}\n\n# after\nserver_port = {{ .Envs.SERVER_PORT }}","handlingStrategy":"validation","validationCode":"tmpl, err := template.New(\"t\").ParseFiles(absFile)\nif err != nil { return fmt.Errorf(\"%s has invalid template syntax: %w\", absFile, err) }\nif err := tmpl.Execute(io.Discard, config.GetValues()); err != nil { return fmt.Errorf(\"%s render check failed: %w\", absFile, err) }","typeGuard":null,"tryCatchPattern":"if err := legacy.LoadConfigure(path); err != nil && strings.Contains(err.Error(), \"render extra config\") { /* message names absFile; fix that file's template and reload */ }","preventionTips":["Escape literal {{ }} in non-template fragments","Pre-render include files in a test job","Use .Envs.<UPPER> naming consistently"],"tags":["config","template","include","legacy-ini","frpc"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}