vitessio/vitess · error

API registered but not handled. Please open an issue at http

Error message

API registered but not handled. Please open an issue at https://github.com/vitessio/vitess/issues/new/choose

What it means

The vtorc debug API router dispatches registered endpoints in a switch; the default branch handles endpoints that are registered but have no handler case. The code comments say this is unreachable in correct code — reaching it means an API path was registered in getACLPermissionLevelForAPI/routing but the ServeHTTP switch was not updated. It is an internal invariant violation surfaced as a 500.

Source

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

		enableGlobalRecoveriesAPIHandler(response)
	case healthAPI:
		healthAPIHandler(response, request)
	case problemsAPI:
		problemsAPIHandler(response, request)
	case errantGTIDsAPI:
		errantGTIDsAPIHandler(response, request)
	case detectionAnalysisAPI:
		detectionAnalysisAPIHandler(response, request)
	case databaseStateAPI:
		databaseStateAPIHandler(response)
	case configAPI:
		configAPIHandler(response)
	case shardQuorumAPI:
		shardQuorumAPIHandler(response)
	default:
		// This should be unreachable. Any endpoint which isn't registered is automatically redirected to /debug/status.
		// This code will only be reachable if we register an API but don't handle it here. That will be a bug.
		http.Error(response, "API registered but not handled. Please open an issue at https://github.com/vitessio/vitess/issues/new/choose", http.StatusInternalServerError)
	}
}

// getACLPermissionLevelForAPI returns the acl permission level that is required to run a given API
func getACLPermissionLevelForAPI(apiEndpoint string) string {
	switch apiEndpoint {
	case problemsAPI, errantGTIDsAPI:
		return acl.MONITORING
	case disableGlobalRecoveriesAPI, enableGlobalRecoveriesAPI:
		return acl.ADMIN
	case detectionAnalysisAPI, configAPI:
		return acl.MONITORING
	case healthAPI, databaseStateAPI:
		return acl.MONITORING
	case shardQuorumAPI:
		return acl.MONITORING
	}
	return acl.ADMIN

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check vtorc/server/api.go ServeHTTP switch and add a case for the unhandled endpoint
  2. Verify you are running an unmodified vitess release; if patched, complete the registration
  3. Open an issue at https://github.com/vitessio/vitess/issues/new/choose as the message instructs
  4. As a workaround use a different registered endpoint that exposes equivalent data

Example fix

// before (in ServeHTTP switch)
default:
	http.Error(response, "API registered but not handled...", http.StatusInternalServerError)
// after
	case myNewAPI:
		myNewAPIHandler(response)
default:
	http.Error(response, "API registered but not handled...", http.StatusInternalServerError)
Defensive patterns

Strategy: validation

Validate before calling

// only call endpoints registered in getACLPermissionLevelForAPI / the ServeHTTP switch
knownEndpoints := map[string]bool{"problems": true, "errant-gtids": true, "database-state": true, "config": true}
if !knownEndpoints[endpoint] {
	// skip; endpoint is unregistered or known-broken
}

Try / catch

resp, err := http.Get(vtorcURL + path)
if err == nil && resp.StatusCode == 500 && strings.Contains(body, "API registered but not handled") {
	log.Error("vtorc API routing bug; report to vitess issues")
}

Prevention

When it happens

Trigger: Requesting a vtorc /debug/ API endpoint whose constant was added to registration (e.g. in the endpoint list or ACL mapping) but whose case was omitted from the switch in ServeHTTP. Typically happens after a partial contribution of a new API endpoint.

Common situations: Running a dev build or patched vitess where a new vtorc API endpoint was half-added; or a version mismatch where routing tables and handlers disagree.

Related errors


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