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

  1. Fix the template syntax in the ServiceTemplate.Content (check that every {{ if }}/{{ range }} has a matching {{ end }})
  2. 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
  3. Restore the stock cloudflared service template if it was modified
  4. 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

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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/11b2ab5e164babc8. Report an issue: GitHub.