vitessio/vitess · warning

invalid health-check path: %q expected path: / or /cell/<ce

Error message

invalid health-check path: %q  expected path: / or /cell/<cell> or /keyspace/<keyspace> or /tablet/mysql_hostname

What it means

The vtgate health-check cache status endpoint accepts item paths of the form `/`, `/cell/<cell>`, `/keyspace/<keyspace>` or `/tablet/<host>`; anything else (an item path without exactly two `/`-split parts) is rejected with this error listing the expected formats. It is input validation for the health-check filter path.

Source

Thrown at go/vt/vtgate/api.go:106

	return parts[1]
}

func initAPI(hc discovery.HealthCheck) {
	// Healthcheck real time status per (cell, keyspace, tablet type, metric).
	handleCollection("health-check", func(r *http.Request) (any, error) {
		cacheStatus := hc.CacheStatus()

		itemPath := getItemPath(r.URL.Path)
		if itemPath == "" {
			return cacheStatus, nil
		}
		parts := strings.SplitN(itemPath, "/", 2)
		collectionFilter := parts[0]
		if collectionFilter == "" {
			return cacheStatus, nil
		}
		if len(parts) != 2 {
			return nil, fmt.Errorf("invalid health-check path: %q  expected path: / or /cell/<cell> or /keyspace/<keyspace> or /tablet/mysql_hostname", itemPath)
		}
		value := parts[1]

		switch collectionFilter {
		case "cell":
			{
				filteredStatus := make(discovery.TabletsCacheStatusList, 0)
				for _, tabletCacheStatus := range cacheStatus {
					if tabletCacheStatus.Cell == value {
						filteredStatus = append(filteredStatus, tabletCacheStatus)
					}
				}
				return filteredStatus, nil
			}
		case "keyspace":
			{
				filteredStatus := make(discovery.TabletsCacheStatusList, 0)
				for _, tabletCacheStatus := range cacheStatus {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Use one of the supported path forms: /, /cell/<cell>, /keyspace/<keyspace>, /tablet/<host>.
  2. Fix the URL builder to always append a value after the filter prefix.
  3. Check for trailing/extra slashes or empty segments in the request path.

Example fix

// before
GET /health/cache/cell/
// after
GET /health/cache/cell/zone-1
Defensive patterns

Strategy: validation

Validate before calling

validPath := func(p string) bool {
    return p == "/" || strings.HasPrefix(p, "/cell/") ||
        strings.HasPrefix(p, "/keyspace/") || strings.HasPrefix(p, "/tablet/")
}
if !validPath(itemPath) {
    return fmt.Errorf("bad health path %q", itemPath)
}

Try / catch

if strings.Contains(respBody, "invalid health-check path") {
    // fix the URL to one of the documented forms and retry
}

Prevention

When it happens

Trigger: Calling the health-check status API with an itemPath lacking the `<filter>/<value>` structure — e.g. a bare name without a value or an over/nested malformed path when parsing cache status request paths.

Common situations: Malformed URLs to the vtgate health endpoint; automation building paths with missing values (`/cell/`) or extra slashes; copy-paste errors in dashboards/scripts.

Related errors


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