router

Routes requests to clusters based on path prefix and host header.
On this page

Routes requests to clusters based on path prefix and host header.

Configuration Notes

If a preceding filter (such as path_rewrite or url_rewrite) has set [rewritten_path], the router matches against the rewritten path. Otherwise, it uses the original request path.

Sets ctx.cluster for downstream filters but does not pick an endpoint or forward the request. The load_balancer filter reads ctx.cluster to select an endpoint.

Longest prefix wins. Routes without host match any host. Header restrictions use AND semantics with case-sensitive matching.

Header restrictions see the request as earlier filters in the pipeline left it: a header they set or added matches by its new value, and one they removed no longer matches, so a classifier can promote a fact to an x-praxis-* header and route on it. A routed header that earlier filters gave two different values fails the request instead of routing on a guess. host is always read from the request as received.

Configuration

FieldTypeRequiredDescription
json_alias_headerstringnoReserved for the experimental, unimplemented JSON alias feature. Only present under the router-json-aliases feature, and even then it has no effect: any route setting json_aliases is rejected at startup. Default builds do not accept this key.
json_alias_max_body_bytesintegernoReserved for the experimental, unimplemented JSON alias feature. Only present under the router-json-aliases feature, and even then it has no effect: any route setting json_aliases is rejected at startup. Default builds do not accept this key.
routesRouterRouteConfig[]noRoute table entries.
routes[].pathstringnoExact path to match. Exactly one of path or path_prefix must be set.
routes[].path_prefixstringnoPath prefix to match; the longest matching prefix wins. Exactly one of path or path_prefix must be set.
routes[].clusterstringyesName of the cluster to route matched requests to.
routes[].headersobject<string, string>noRequest headers to match. All specified headers must be present with matching values (AND semantics, case-sensitive). Headers that earlier filters in the pipeline set, added, or removed are matched as those filters left them.
routes[].hoststringnoHost to match. If set, the route only applies to this host.
routes[].json_aliasesJsonAlias[]noNot implemented. Setting this is rejected at startup. Only present under the experimental router-json-aliases feature.
routes[].json_aliases[].fieldstringyesRequest JSON field whose string value is compared with pattern.
routes[].json_aliases[].matchstringyesExact or single-wildcard pattern for the configured field value.
routes[].json_aliases[].targetstringnoReplacement value; omitted aliases preserve the original value.
routes[].retry_policyRetryPolicynoOptional per-route retry policy override.
routes[].retry_policy.max_retriesintegernoMaximum number of retry attempts after the initial try. None means inherit from the merge parent / use the legacy default.
routes[].retry_policy.retriable_status_codesHttpStatusCode[]noExplicit HTTP status codes that are retriable.
routes[].retry_policy.retriable_conditions(connect_failure | reset | refused_stream | status5xx)[]noNamed retriable conditions (connect failure, reset, 5xx, …).
routes[].retry_policy.per_try_timeout_msintegernoIndependent timeout for a single upstream attempt, in milliseconds.
routes[].retry_policy.request_timeout_msintegernoOverall request deadline across all attempts, in milliseconds. When unset, the overall-timeout guard is skipped.
routes[].retry_policy.backoffBackoffConfignoExponential backoff between attempts.
routes[].retry_policy.backoff.base_interval_msintegeryesExponential base interval in milliseconds.
routes[].retry_policy.backoff.max_interval_msintegeryesMaximum capped interval in milliseconds.
routes[].retry_policy.configuredboolnoWhether this policy came from operator configuration rather than the built-in legacy default. Endpoint reselection on retry is enabled only for configured policies; the legacy default preserves the historical retry-same-endpoint semantics.
routes[].retry_policy.retry_budgetRetryBudgetConfignoToken-bucket retry budget.
routes[].retry_policy.retry_budget.percentnumberyesCaps accumulated retry tokens (burst) at this percentage of in-flight requests (0.0..=100.0); the sustained rate is min_retries_per_second.
routes[].retry_policy.retry_budget.min_retries_per_secondintegernoFloor on tokens per second even at low traffic.
routes[].retry_policy.retry_body_limit_bytesintegernoMax request body size eligible for replay (bytes). Defaults to 64 KiB.
routes[].retry_policy.allow_non_idempotentboolnoAllow retries for non-idempotent methods (POST/PATCH) when true.
routes[].hedge_policyHedgePolicynoOptional per-route hedged-request policy. When max_attempts is greater than 1 and the hedged-requests feature is enabled, an idempotent request buffers its body, races it across healthy endpoints in its cluster, and returns the first 2xx, 3xx, or 4xx response, cancelling the other attempts. max_attempts of 1, CONNECT, Upgrade, non-idempotent methods, and application/grpc requests keep a single upstream attempt. Absent means one upstream attempt.
routes[].hedge_policy.initial_requestsintegeryesAttempts started immediately, including the primary. 1 sends the primary and waits for per_try_timeout_ms before any copy. Values greater than 1 fan out that many attempts at once.
routes[].hedge_policy.max_attemptsintegeryesTotal attempts for one client request, including the primary. Must be at least initial_requests and at most 8.
routes[].hedge_policy.per_try_timeout_msintegernoMilliseconds to wait, with no successful response, before starting the next attempt. Required when max_attempts is greater than initial_requests. Must be omitted when they are equal.
routes[].hedge_policy.budget_percentnumberyesCap on hedge copies as a percent of requests on this route (0.0..=100.0). The percent must be a multiple of 0.01 (one basis point). A finer value is rejected so the loaded percent is the percent that is enforced. The primary attempt is not counted. 0 disables copies. While no copy is in flight, any positive budget admits one, so a single active request can still hedge. Further copies stay under the percent: 10 keeps about one extra attempt per ten active requests. The budget also caps the initial fan-out. At 100, one active request can hold one copy, so initial_requests: 3 starts the primary and one copy.
multi_level_subdomain_matchingboolnoEnable multi-level subdomain matching for wildcard hosts. When false (default), *.example.com matches only single-level subdomains like foo.example.com. When true, it also matches multi-level subdomains like foo.bar.example.com (suffix match). Some control planes (e.g. Kubernetes Gateway API) require this.

Example

filter: router
routes:
  - path_prefix: "/"
    cluster: default