thanos-io/thanos · error

failed to execute template

Error message

failed to execute template

What it means

After the URL template parses successfully, Thanos executes it with text/template's Execute into a bytes.Buffer, passing an Expression{Expr: url.QueryEscape(expr)} as data. If the template's actions reference fields that don't exist on Expression, use invalid pipeline functions, or a writer error occurs on the buffer, the wrapped "failed to execute template" error is returned and no URL is produced.

Solutions

  1. Use only {{.Expr}} as the field: the data passed to Execute is Expression{Expr: escapedExpression} and nothing else.
  2. Run the template through Thanos's validateTemplate (cmd/thanos/rule.go) which executes it with Expression{Expr: "test_expr"} to catch field errors before startup.
  3. Replace unsupported constructs (sprig functions, custom pipelines) with plain Go text/template builtins like urlquery/printf.
  4. Check the underlying template.ExecError in the wrapped error message: it names the exact field or function that failed.

Example fix

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

Strategy: validation

Validate before calling

func executesAgainstExpression(s string) bool {
    t, err := texttemplate.New("check").Parse(s)
    if err != nil {
        return false
    }
    var buf bytes.Buffer
    return t.Execute(&buf, Expression{Expr: "test_expr"}) == nil
}

Type guard

null

Try / catch

var buf bytes.Buffer
if err := t.Execute(&buf, escapedExpr); err != nil {
    return "", fmt.Errorf("template execution failed (only .Expr is available): %w", err)
}

Prevention

When it happens

Trigger: Calling the URL builder with a syntactically valid template that references a non-existent field (e.g. {{.PromQL}} or {{.Query}} instead of {{.Expr}}), calls a method on a nil/wrong type, or uses an unknown function, so t.Execute(&buf, escapedExpr) fails.

Common situations: Users guess field names from other templating systems (Grafana uses $expr, Prometheus templating uses $value); copy-pasting templates built for text/template with different data models; templates that index or call methods unsupported by the Expression struct.

Related errors


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

Appendix: source

Thrown at cmd/thanos/rule.go:1135

	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)
	}
	return nil
}

// Filter out PromQL related warnings from warning response and keep store related warnings only.

View on GitHub (pinned to 35b8b99117)