vitessio/vitess · error

err.Error() (template execute failure)

Error message

err.Error() (template execute failure)

What it means

WriteScatterStats renders the scatter-query statistics debug page by executing an HTML template against gathered results. If t.Execute fails while writing to the HTTP response (template data mismatch, or the client connection is broken mid-write), the handler calls http.Error with the raw error text and a 500 status. This surfaces internal template-execution or network-write failures to the operator's browser.

Source

Thrown at go/vt/vtgate/executor_scatter_stats.go:133

	logz.StartHTMLTable(w)
	defer logz.EndHTMLTable(w)

	results, err := e.gatherScatterStats()
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	t := template.New("template")
	t, err = t.Parse(statsHTML)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	err = t.Execute(w, results)
	if err != nil {
		http.Error(w, err.Error(), 500)
	}

	_, err = fmt.Fprintf(w, "Percentage of time spent on scatter queries: %2.2f%%", results.PercentTimeScatter)
	if err != nil {
		http.Error(w, err.Error(), 500)
	}
}

const statsHTML = `
<thead>
	<tr>
		<th>Query</th>
		<th># of executions</th>
		<th>Avg time/query</th>
		<th>% time of reads</th>
		<th>% time of scatters</th>
		<th>% of reads</th>
		<th>% of scatters</th>

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check vtgate logs for the underlying template/write error to confirm whether it was a client disconnect (benign) or a template bug
  2. Retry the request with the connection held open; verify the full page renders
  3. If it reproduces with a live connection, file/inspect a vitess issue — the template and results types are internal and should always match
  4. Verify no proxy/load-balancer between client and vtgate is cutting long responses early
Defensive patterns

Strategy: fallback

Validate before calling

// before calling the endpoint, verify it is reachable
resp, err := http.Get("http://vtgate:15001/scatterStats")
if err != nil || resp.StatusCode != 200 {
	// fall back to vtgate /debug/vars scatter counters
}

Try / catch

// client-side
resp, err := http.Get(url)
if err != nil {
	log.Warn("scatterStats fetch failed", slog.Any("error", err))
	return fallbackStats()
}
defer resp.Body.Close()

Prevention

When it happens

Trigger: Hitting the /scatterStats debug endpoint on VTGate when the template execution fails: the underlying writer errors out (client disconnects mid-response), or the template cannot render the gathered ScatterStats results. Note the handler does not return after this http.Error, so a second write may also be attempted.

Common situations: Monitoring or a browser tab polling /scatterStats closes the connection while the page is still streaming; the response body has already been partially written so the 500 status line cannot actually be delivered.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/5d937011885ddaa0. Report an issue: GitHub.