cloudflare/cloudflared · error
error generating %s template: %v
Error message
error generating %s template: %v
What it means
This error is returned by ServiceTemplate.Generate when the embedded template content fails to parse. Go's text/template package parses st.Content before execution; a parse failure means the template syntax itself is malformed, so no file can ever be rendered. The message includes st.Path (the template's logical identifier, e.g. the launchd plist path) and the underlying parse error.
Source
Thrown at cmd/cloudflared/service_template.go:38
}
type ServiceTemplateArgs struct {
Path string
ExtraArgs []string
}
func (st *ServiceTemplate) ResolvePath() (string, error) {
resolvedPath, err := homedir.Expand(st.Path)
if err != nil {
return "", fmt.Errorf("error resolving path %s: %v", st.Path, err)
}
return resolvedPath, nil
}
func (st *ServiceTemplate) Generate(args *ServiceTemplateArgs) error {
tmpl, err := template.New(st.Path).Parse(st.Content)
if err != nil {
return fmt.Errorf("error generating %s template: %v", st.Path, err)
}
resolvedPath, err := st.ResolvePath()
if err != nil {
return err
}
if _, err = os.Stat(resolvedPath); err == nil {
return errors.New(serviceAlreadyExistsWarn(resolvedPath))
}
var buffer bytes.Buffer
err = tmpl.Execute(&buffer, args)
if err != nil {
return fmt.Errorf("error generating %s: %v", st.Path, err)
}
fileMode := os.FileMode(0o644)
if st.FileMode != 0 {
fileMode = st.FileMode
}View on GitHub (pinned to 2253eeeb25)
Solutions
- Fix the template syntax in the ServiceTemplate.Content (check that every {{ if }}/{{ range }} has a matching {{ end }})
- If using a custom template, validate it with template.New(path).Parse(content) in isolation to see the exact line/column of the parse error
- Restore the stock cloudflared service template if it was modified
- Call Generate only after successfully parsing the template once at startup to fail fast
Example fix
// before (broken template)
var tpl = `...{{ if .Ephemeral }}...{{ end }` // missing closing brace
// after
var tpl = `...{{ if .Ephemeral }}...{{ end }}` Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate template syntax before calling Generate
func validateTemplate(path, content string) error {
_, err := template.New(path).Parse(content)
return err
}
if err := validateTemplate(st.Path, st.Content); err != nil {
return fmt.Errorf("template %s is malformed: %w", st.Path, err)
} Type guard
func templateParses(content string) bool {
_, err := template.New("probe").Parse(content)
return err == nil
} Try / catch
if err := st.Generate(args); err != nil {
if strings.HasPrefix(err.Error(), "error generating") && strings.Contains(err.Error(), "parse") {
// malformed template: log content, fix template, do not retry
}
return err
} Prevention
- Validate every template with Parse at program start or in unit tests
- Count {{ }} delimiters and matching {{ end }} tokens when hand-editing templates
- Keep templates as checked-in constants with tests that render them against sample args
- Avoid building template strings by concatenation at runtime
When it happens
Trigger: Calling Generate() on a ServiceTemplate whose Content field contains invalid template syntax — e.g. an unclosed {{ if }}, {{ range }} without {{ end }}, or malformed {{ .Field }} pipelines. For the launchd service this happens inside installLaunchd when the built-in plist template constant was modified or corrupted.
Common situations: Hand-editing a custom plist template with unbalanced template actions; accidentally copying template text containing literal {{ }} from docs; build-time string corruption; a new template field referenced with a typo like {{ .Servcie }}</code> combined with bad syntax so it fails at parse rather than execution.
Related errors
- error generating %s: %v
- error creating %s: %v
- error writing %s: %v
- error deleting %s: %v
- error determining executable path: %w
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/11b2ab5e164babc8.
Report an issue: GitHub.