thanos-io/thanos · error

failed to parse template

Error message

failed to parse template

What it means

In Thanos's rule UI URL templating (thanos rule, --alert.query-template style), the user-provided Go text/template used to build links like "/graph?g0.expr={{.Expr}}" is parsed with text/template. If the template string is not syntactically valid Go template syntax, errors.Wrap produces "failed to parse template" and URL generation aborts. The template is executed with an Expression struct exposing only the .Expr field (URL-query-escaped PromQL).

Solutions

  1. Check the template string for balanced, valid Go template actions: every {{ must have a matching }} and valid syntax (see https://pkg.go.dev/text/template).
  2. Only reference fields that exist on the Expression data: use {{.Expr}} (the URL-escaped PromQL expression); other fields will fail at execute time, but syntax errors surface here.
  3. Test the template offline with template.New("test").Parse(tmpl) in a scratch Go program or rely thanos's own validateTemplate path before deploying.
  4. If the flag comes from a YAML/Env config, verify shell/JSON escaping did not swallow or duplicate braces.

Example fix

// before
tmpl := "/graph?g0.expr={{{.Expr}}}&g0.tab=1"
// after
tmpl := "/graph?g0.expr={{.Expr}}&g0.tab=1"
Defensive patterns

Strategy: validation

Validate before calling

func validTemplate(s string) bool {
    _, err := texttemplate.New("check").Parse(s)
    return err == nil
}
// require validTemplate(tmpl) before passing to thanos rule flags

Type guard

null

Try / catch

if _, err := texttemplate.New("url").Parse(tmpl); err != nil {
    return fmt.Errorf("invalid url template %q: %w", tmpl, err)
}

Prevention

When it happens

Trigger: Calling the URL-template function (invoked when generating external query links for alerts/rules) with a tmpl string containing malformed Go template syntax, e.g. unbalanced {{ }} braces, an unclosed action, or invalid pipeline syntax, causing texttemplate.New("url").Parse(tmpl) to fail.

Common situations: Operators hand-write the URL template flag and typo the delimiters (e.g. "/graph?g0.expr={{{.Expr}}}" or a stray {{without an end}}); copying a Jinja2/Handlebars-style template instead of Go syntax; quoting issues in YAML/CLI mangle the braces.

Understand the failure class

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/e3c107e772bb0992. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/rule.go:1130

	metrics.configSuccess.Set(1)
	metrics.configSuccessTime.Set(float64(time.Now().UnixNano()) / 1e9)

	metrics.rulesLoaded.Reset()
	for _, group := range ruleMgr.RuleGroups() {
		metrics.rulesLoaded.WithLabelValues(group.PartialResponseStrategy.String(), group.OriginalFile, group.Name()).Set(float64(len(group.Rules())))
	}
	return errs.Err()
}

func tableLinkForExpression(tmpl string, expr string) (string, error) {
	// template example: "/graph?g0.expr={{.Expr}}&g0.tab=1"
	escapedExpression := url.QueryEscape(expr)

	escapedExpr := Expression{Expr: escapedExpression}
	t, err := texttemplate.New("url").Parse(tmpl)
	if err != nil {
		return "", errors.Wrap(err, "failed to parse template")
	}

	var buf bytes.Buffer
	if err := t.Execute(&buf, escapedExpr); err != nil {
		return "", errors.Wrap(err, "failed to execute template")
	}
	return buf.String(), nil
}

func validateTemplate(tmplStr string) error {
	tmpl, err := template.New("test").Parse(tmplStr)
	if err != nil {
		return fmt.Errorf("failed to parse the template: %w", err)
	}
	var buf bytes.Buffer
	err = tmpl.Execute(&buf, Expression{Expr: "test_expr"})
	if err != nil {
		return fmt.Errorf("failed to execute the template: %w", err)

View on GitHub (pinned to 35b8b99117)