vitessio/vitess · error

err.Error() (EnableRecovery failure)

Error message

err.Error() (EnableRecovery failure)

What it means

This is the HTTP 500 body produced by the vtorc /enable-global-recoveries API handler when logic.EnableRecovery() returns an error. VTOrc refuses to re-enable global recovery processing because an underlying step (e.g. writing orchestrator settings/leadership state) failed. The raw error text is forwarded verbatim so the caller can see the cause.

Source

Thrown at go/vt/vtorc/server/api.go:253

	}
	returnAsJSON(response, http.StatusOK, results)
}

// disableGlobalRecoveriesAPIHandler is the handler for the disableGlobalRecoveriesAPI endpoint
func disableGlobalRecoveriesAPIHandler(response http.ResponseWriter) {
	err := logic.DisableRecovery()
	if err != nil {
		http.Error(response, err.Error(), http.StatusInternalServerError)
		return
	}
	writePlainTextResponse(response, "Global recoveries disabled", http.StatusOK)
}

// enableGlobalRecoveriesAPIHandler is the handler for the enableGlobalRecoveriesAPI endpoint
func enableGlobalRecoveriesAPIHandler(response http.ResponseWriter) {
	err := logic.EnableRecovery()
	if err != nil {
		http.Error(response, err.Error(), http.StatusInternalServerError)
		return
	}
	writePlainTextResponse(response, "Global recoveries enabled", http.StatusOK)
}

// LegacyDetectionAnalysisJSON is a wrapper to *inst.DetectionAnalysis that
// provides the AnalyzedInstanceAlias field in the old string-based format.
type LegacyDetectionAnalysisJSON struct {
	*inst.DetectionAnalysis
}

// NewLegacyDetectionAnalysisJSON wraps a *inst.DetectionAnalysis with *LegacyDetectionAnalysisJSON.
func NewLegacyDetectionAnalysisJSON(da *inst.DetectionAnalysis) *LegacyDetectionAnalysisJSON {
	return &LegacyDetectionAnalysisJSON{da}
}

// MarshalJSON converts a *LegacyDetectionAnalysisJSON to the legacy format JSON,
// outputting AnalyzedInstanceAlias and AnalyzedInstancePrimaryAlias as strings.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the vtorc logs for the full EnableRecovery error to identify the failing backend call
  2. Verify vtorc's topology/topo connectivity and credentials, then retry the endpoint
  3. Confirm the vtorc instance is healthy (/health) and that its backing storage is reachable before retrying

Example fix

// before: raw 500 with err.Error()
http.Error(response, err.Error(), http.StatusInternalServerError)
// after: log and return a wrapped, actionable message
log.Error("EnableRecovery failed", slog.Any("error", err))
http.Error(response, fmt.Sprintf("failed to enable global recoveries: %v", err), http.StatusInternalServerError)
Defensive patterns

Strategy: try-catch

Validate before calling

resp, err := http.Get(vtorcURL + "/health")
if err != nil || resp.StatusCode != http.StatusOK {
    return fmt.Errorf("vtorc unhealthy, skipping enable-global-recoveries")
}

Try / catch

resp, err := http.Post(vtorcURL+"/enable-global-recoveries", "", nil)
if err != nil {
    return err
}
if resp.StatusCode != http.StatusOK {
    body, _ := io.ReadAll(resp.Body)
    return fmt.Errorf("enable global recoveries failed (%d): %s", resp.StatusCode, body)
}

Prevention

When it happens

Trigger: POST/GET to the vtorc /enable-global-recoveries endpoint while EnableRecovery fails — typically because the backend it writes recovery-enablement state to (the orchestrator backing store / topo) is unavailable or rejects the write.

Common situations: VTOrc's backing store or topology server is down or misconfigured; permissions prevent writing the recovery-enabled flag; running the endpoint against a vtorc instance that lost its backend connection.

Related errors


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