istio/istio · error

invalid path, must be in form of regex pattern %v

Error message

invalid path, must be in form of regex pattern %v

What it means

validateAppKubeProber rejects a prober map key (URL path) that does not match appProberPattern: ^/(app-health|app-lifecycle)/[^/]+/(livez|readyz|startupz|prestopz|poststartz)$. The agent only serves taken-over Kubernetes probes on these exact URL shapes (container name between fixed segments, one of the five probe verbs), because these paths are what kubelet is reconfigured to call.

Source

Thrown at pilot/cmd/pilot-agent/status/server.go:395

// * If we exceed 10 redirects, the probe fails
// * If we redirect somewhere external, the probe succeeds (https://github.com/kubernetes/kubernetes/blob/b152001f459/pkg/probe/http/http.go#L130)
// * If we redirect to the same address, the probe will follow the redirect
func redirectChecker() func(*http.Request, []*http.Request) error {
	return func(req *http.Request, via []*http.Request) error {
		if req.URL.Hostname() != via[0].URL.Hostname() {
			return http.ErrUseLastResponse
		}
		// Default behavior: stop after 10 redirects.
		if len(via) >= 10 {
			return errors.New("stopped after 10 redirects")
		}
		return nil
	}
}

func validateAppKubeProber(path string, prober *Prober) error {
	if !appProberPattern.MatchString(path) {
		return fmt.Errorf(`invalid path, must be in form of regex pattern %v`, appProberPattern)
	}
	count := 0
	if prober.HTTPGet != nil {
		count++
	}
	if prober.TCPSocket != nil {
		count++
	}
	if prober.GRPC != nil {
		count++
	}
	if count != 1 {
		return fmt.Errorf(`invalid prober type, must be one of type httpGet, tcpSocket or gRPC`)
	}
	if prober.HTTPGet != nil && prober.HTTPGet.Port.Type != apimirror.Int {
		return fmt.Errorf("invalid prober config for %v, the port must be int type", path)
	}
	if prober.TCPSocket != nil && prober.TCPSocket.Port.Type != apimirror.Int {

View on GitHub (pinned to 8dc789c5cf)

Solutions

  1. Regenerate paths with FormatProberURL(container) — it emits exactly the five accepted URLs (readyz, livez, startupz, prestopz, poststartz)
  2. Fix the offending key to match /(app-health|app-lifecycle)/<container>/<verb> with a single non-slash container segment
  3. Re-inject the workload with the matching Istio revision instead of crafting the JSON by hand
  4. Check for other mutating webhooks rewriting the injected JSON

Example fix

// before (hand-written probers map key)
{"/healthz/myapp": {"httpGet": {"path": "/", "port": 8080}}}
// after (use the agent's own URL formatter)
path, _, _, _, _ := FormatProberURL("myapp") // "/app-health/myapp/readyz"
probers := map[string]*Prober{path: {HTTPGet: &HTTPGetAction{Path: "/", Port: 8080}}}
Defensive patterns

Strategy: validation

Validate before calling

// Only emit paths the agent accepts: derive them from FormatProberURL
var appProberPattern = regexp.MustCompile(`^/(app-health|app-lifecycle)/[^/]+/(livez|readyz|startupz|prestopz|poststartz)$`)
for path := range probers {
    if !appProberPattern.MatchString(path) {
        return fmt.Errorf("bad prober path %q", path)
    }
}

Prevention

When it happens

Trigger: A key in the decoded KubeAppProbers map like "/healthz", "/app-health/myapp/notaverb", or "/app-health/a/b/readyz" (two path segments in the container slot) fails MatchString during NewServer validation.

Common situations: Custom injectors or tools writing the probers annotation/env themselves instead of using FormatProberURL; version skew where an older injector emitted a different URL scheme than the agent's regex expects; manual editing of injected JSON with a 'cleaned up' path.

Related errors


AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15). Data as JSON: /api/errors/37a1b13a392e6896. Report an issue: GitHub.