vitessio/vitess · warning
failed to write rendered config: %v
Error message
failed to write rendered config: %v
What it means
After writing the rendered config to the temp file, the handler reads it back with io.Copy(tmp, w) to stream it to the client. If copying to the ResponseWriter fails, it returns 500 'failed to write rendered config'. This is almost always a client-side/connection issue rather than a server bug.
Source
Thrown at go/viperutil/debug/handler.go:76
// then copy it to the response.
//
// (Sadly, viper does not yet have a WriteConfigTo(w io.Writer), so we have
// to do this little hacky workaround).
v.SetConfigType(format)
tmp, err := os.CreateTemp("", "viper_debug")
if err != nil {
http.Error(w, fmt.Sprintf("failed to render config to tempfile: %v", err), http.StatusInternalServerError)
return
}
defer os.Remove(tmp.Name())
if err := v.WriteConfigAs(tmp.Name()); err != nil {
http.Error(w, fmt.Sprintf("failed to render config to tempfile: %v", err), http.StatusInternalServerError)
return
}
if _, err := io.Copy(w, tmp); err != nil {
http.Error(w, fmt.Sprintf("failed to write rendered config: %v", err), http.StatusInternalServerError)
return
}
default:
http.Error(w, "unsupported config format", http.StatusBadRequest)
}
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Retry the request and keep the connection open until the response completes.
- Increase client/proxy timeouts (e.g. curl --max-time, LB idle timeout).
- If large configs hit limits, request a narrower format or subset of the config.
- Ignore transient 'broken pipe' occurrences; only investigate if it reproduces with a stable client.
Example fix
// before curl --max-time 1 'http://localhost:15000/debug/config?format=json' // after curl --max-time 30 'http://localhost:15000/debug/config?format=json'
Defensive patterns
Strategy: retry
Try / catch
for attempt := 0; attempt < 3; attempt++ {
resp, err := http.Get(cfgURL)
if err != nil {
time.Sleep(backoff(attempt))
continue
}
body, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr == nil {
return body, nil
}
// read interrupted mid-body: retry
} Prevention
- Use generous client timeouts (30s+) when fetching debug config endpoints.
- Avoid closing the client or killing curl before the response body completes.
- Increase LB/proxy idle timeouts for debug endpoints.
When it happens
Trigger: io.Copy(w, tmp) returns an error while streaming the rendered config — typically the HTTP client disconnected mid-response, or the underlying connection was reset/closed before the body completed.
Common situations: User closes browser tab or curl with --max-time before the response completes; load balancer timeout cutting the response; network interruption between client and vitess process.
Related errors
- unable to close file: %v
- http server stopped: %w
- no route variable found with name %s
- %w: parsing %s at position %d
- must specify at least one keyspace_shard to delete (got %+v)
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/940910ab97513ee7.
Report an issue: GitHub.