istio/istio · error · ListenerStatusConfigError

protocol %q is unsupported. hint: %q (uppercase) may be supp

Error message

protocol %q is unsupported. hint: %q (uppercase) may be supported

What it means

listenerProtocolToIstio matches listener protocols case-sensitively against the supportedProtocols set ({HTTP, HTTPS, TLS, TCP, HBONE}, see listener.go:50-55). If the exact string is not in the set but its UPPERCASE form is, this error is returned with a hint naming the capitalized value. It exists to catch casing mistakes like 'http' instead of 'HTTP' rather than silently accepting or rejecting them.

Source

Thrown at pilot/pkg/config/kube/agentgateway/listener.go:207

		return string(p), nil
	case gatewayv1.TLSProtocolType:
		return string(p), nil
	case gatewayv1.TCPProtocolType:
		if !features.EnableAlphaGatewayAPI {
			return "", fmt.Errorf("protocol %q is only supported when the alpha Gateway API is enabled", p)
		}
		return string(p), nil
	// Our own custom types
	case gatewayv1.ProtocolType(protocol.HBONE):
		if name != constants.ManagedGatewayMeshController && name != constants.ManagedGatewayEastWestController &&
			name != constants.ManagedAgentgatewayWaypointController && name != constants.ManagedAgentgatewayController {
			return "", fmt.Errorf("protocol %q is only supported for HBONE-enabled gateways/waypoints", p)
		}
		return string(p), nil
	}
	up := gatewayv1.ProtocolType(strings.ToUpper(string(p)))
	if supportedProtocols.Contains(up) {
		return "", fmt.Errorf("protocol %q is unsupported. hint: %q (uppercase) may be supported", p, up)
	}
	// Note: the gatewayv1.UDPProtocolType is explicitly left to hit this path
	return "", fmt.Errorf("protocol %q is unsupported", p)
}

// Same as buildHostnameMatch in gateway/conversion.go
// buildHostnameMatch generates a Gateway.spec.servers.hosts section from a listener
func buildHostnameMatch(ctx krt.HandlerContext, localNamespace string, namespaces krt.Collection[*corev1.Namespace], l gatewayv1.Listener) []string {
	// We may allow all hostnames or a specific one
	hostname := "*"
	if l.Hostname != nil {
		hostname = string(*l.Hostname)
	}

	resp := []string{}
	for _, ns := range namespacesFromSelector(ctx, localNamespace, namespaces, l.AllowedRoutes) {
		// This check is necessary to prevent adding a hostname with an invalid empty namespace
		if len(ns) > 0 {

View on GitHub (pinned to 8dc789c5cf)

Solutions

  1. Rewrite the protocol exactly as shown in the hint (e.g., 'http' -> 'HTTP')
  2. Lint manifests against the gateway.networking.k8s.io CRDs so enum/case violations are caught at apply time (kubectl apply --dry-run=server)
  3. Fix the templating/tooling that is altering the casing of the protocol field

Example fix

# before
spec:
  listeners:
  - name: http
    port: 80
    protocol: http
# after
spec:
  listeners:
  - name: http
    port: 80
    protocol: HTTP
Defensive patterns

Strategy: validation

Validate before calling

canonical := sets.New(
    string(gatewayv1.HTTPProtocolType),
    string(gatewayv1.HTTPSProtocolType),
    string(gatewayv1.TLSProtocolType),
    string(gatewayv1.TCPProtocolType),
    string(gatewayv1.ProtocolType(protocol.HBONE)),
)
for _, l := range gw.Spec.Listeners {
    if !canonical.Contains(string(l.Protocol)) {
        up := strings.ToUpper(string(l.Protocol))
        if canonical.Contains(up) {
            return fmt.Errorf("listener %q: protocol %q must be written %q", l.Name, l.Protocol, up)
        }
        return fmt.Errorf("listener %q: unsupported protocol %q", l.Name, l.Protocol)
    }
}

Type guard

func hasCanonicalProtocol(l gatewayv1.Listener) bool {
    switch string(l.Protocol) {
    case "HTTP", "HTTPS", "TLS", "TCP", "HBONE":
        return true
    }
    return false
}

Prevention

When it happens

Trigger: A Gateway listener with protocol written as http, https, tls, tcp (lowercase) or mixed case such as Http. The Gateway API CRD enum normally blocks these, so this is typically hit when objects are constructed programmatically, applied with relaxed/older CRDs, or transformed by templating tools that lowercase strings.

Common situations: Helm/kustomize string transformations lowercasing protocol fields; config generated from code or data files without enum validation; hand-edited manifests; CI that bypasses server-side CRD validation.

Related errors


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