---
title: "Kubernetes IngressRoute"
description: "An IngressRoute is a Traefik CRD is in charge of connecting incoming requests to the Services that can handle them in HTTP."
---

`IngressRoute` is the CRD implementation of a [Traefik HTTP router](../../../http/routing/rules-and-priority.md).

Before creating `IngressRoute` objects, you need to apply the Traefik Kubernetes CRDs such as [Definitions](/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml) and [RBAC](/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml) to your Kubernetes cluster.

This registers the `IngressRoute` kind and other Traefik-specific resources.

## Configuration Example

You can declare an `IngressRoute` as detailed below:

```yaml tab="IngressRoute"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test-name
  namespace: apps

spec:
  ingressClassName: traefik-lb
  entryPoints:
    - web
  parentRefs:
    - name: parent-gateway
      namespace: default  # Optional - defaults to same namespace
  routes:
  - kind: Rule
    # Rule on the Host
    match: Host(`test.example.com`)
    # Attach a middleware
    middlewares:
    - name: middleware1
      namespace: apps
    # Enable Router observability
    observability:
      accessLogs: true
      metrics: true
      tracing: true
    # Set a priority
    priority: 10
    services:
    # Target a Kubernetes Support
    - kind: Service
      name: foo
      namespace: apps
      # Customize the connection between Traefik and the backend
      passHostHeader: true
      port: 80
      responseForwarding:
        flushInterval: 1ms
      scheme: https
      sticky:
        cookie:
          httpOnly: true
          name: cookie
          secure: true
      strategy: wrr
      weight: 10
  tls:
    # Generate a TLS certificate using a certificate resolver
    certResolver: foo
    domains:
    - main: example.net
      sans:
      - a.example.net
      - b.example.net
    # Customize the TLS options
    options:
      name: opt
      namespace: apps
    # Add a TLS certificate from a Kubernetes Secret
    secretName: supersecret
```

## Configuration Options

| Field                                                                                                                                                                                            | Description                                                                                                                                                                                                                                                                                                                                                                      | Default | Required |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------|
| <a id="opt-ingressClassName" href="#opt-ingressClassName" title="#opt-ingressClassName">`ingressClassName`</a> | Defines the [IngressClass](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) cluster resource to use. It replaces the deprecated `kubernetes.io/ingress.class` annotation.<br />The spec field takes precedence over the annotation.                                                                                                               |         | No       |
| <a id="opt-entryPoints" href="#opt-entryPoints" title="#opt-entryPoints">`entryPoints`</a> | List of [entry points](../../../../install-configuration/entrypoints.md) names.<br />If not specified, HTTP routers will accept requests from all EntryPoints in the list of default EntryPoints.                                                                                                                                                                                |         | No       |
| <a id="opt-parentRefs" href="#opt-parentRefs" title="#opt-parentRefs">`parentRefs`</a> | List of references to parent IngressRoute resources for multi-layer routing. When specified, this IngressRoute's routers become children of the referenced parent IngressRoute's routers. See [Multi-Layer Routing](#multi-layer-routing-with-ingressroutes) section for details.                                                                                                |         | No       |
| <a id="opt-parentRefsn-name" href="#opt-parentRefsn-name" title="#opt-parentRefsn-name">`parentRefs[n].name`</a> | Name of the referenced parent IngressRoute resource.                                                                                                                                                                                                                                                                                                                             |         | Yes      |
| <a id="opt-parentRefsn-namespace" href="#opt-parentRefsn-namespace" title="#opt-parentRefsn-namespace">`parentRefs[n].namespace`</a> | Namespace of the referenced parent IngressRoute resource.<br />If not specified, defaults to the same namespace as the child IngressRoute.<br />Cross-namespace references require `allowCrossNamespace` provider option to be enabled.                                                                                                                                          |         | No       |
| <a id="opt-routes" href="#opt-routes" title="#opt-routes">`routes`</a> | List of routes.                                                                                                                                                                                                                                                                                                                                                                  |         | Yes      |
| <a id="opt-routesn-kind" href="#opt-routesn-kind" title="#opt-routesn-kind">`routes[n].kind`</a> | Kind of router matching, only `Rule` is allowed yet.                                                                                                                                                                                                                                                                                                                             | "Rule"  | No       |
| <a id="opt-routesn-match" href="#opt-routesn-match" title="#opt-routesn-match">`routes[n].match`</a> | Defines the [rule](../../../http/routing/rules-and-priority.md#rules) corresponding to an underlying router.                                                                                                                                                                                                                                                                     |         | Yes      |
| <a id="opt-routesn-priority" href="#opt-routesn-priority" title="#opt-routesn-priority">`routes[n].priority`</a> | Defines the [priority](../../../http/routing/rules-and-priority.md#priority-calculation) to disambiguate rules of the same length, for route matching.<br />If not set, the priority is directly equal to the length of the rule, and so the longest length has the highest priority.<br />A value of `0` for the priority is ignored, the default rules length sorting is used.<br />Negative values are supported. | 0       | No       |
| <a id="opt-routesn-middlewares" href="#opt-routesn-middlewares" title="#opt-routesn-middlewares">`routes[n].middlewares`</a> | List of middlewares to attach to the IngressRoute. <br />More information [here](#middleware).                                                                                                                                                                                                                                                                                   | ""      | No       |
| <a id="opt-routesn-middlewaresm-name" href="#opt-routesn-middlewaresm-name" title="#opt-routesn-middlewaresm-name">`routes[n].`<br />`middlewares[m].`<br />`name`</a> | Middleware name.<br />The character `@` is not authorized. <br />More information [here](#middleware).                                                                                                                                                                                                                                                                           |         | Yes      |
| <a id="opt-routesn-middlewaresm-namespace" href="#opt-routesn-middlewaresm-namespace" title="#opt-routesn-middlewaresm-namespace">`routes[n].`<br />`middlewares[m].`<br />`namespace`</a> | Middleware namespace.<br />Can be empty if the middleware belongs to the same namespace as the IngressRoute. <br />More information [here](#middleware).                                                                                                                                                                                                                         |         | No       |
| <a id="opt-routesn-observability-accessLogs" href="#opt-routesn-observability-accessLogs" title="#opt-routesn-observability-accessLogs">`routes[n].`<br />`observability.`<br />`accessLogs`</a> | Defines whether the route will produce [access-logs](../../../../install-configuration/observability/logs-and-accesslogs.md). See [here](../../../http/routing/observability.md) for more information.                                                                                                                                                                           | false   | No       |
| <a id="opt-routesn-observability-metrics" href="#opt-routesn-observability-metrics" title="#opt-routesn-observability-metrics">`routes[n].`<br />`observability.`<br />`metrics`</a> | Defines whether the route will produce [metrics](../../../../install-configuration/observability/metrics.md). See [here](../../../http/routing/observability.md) for more information.                                                                                                                                                                                           | false   | No       |
| <a id="opt-routesn-observability-tracing" href="#opt-routesn-observability-tracing" title="#opt-routesn-observability-tracing">`routes[n].`<br />`observability.`<br />`tracing`</a> | Defines whether the route will produce [traces](../../../../install-configuration/observability/tracing.md). See [here](../../../http/routing/observability.md) for more information.                                                                                                                                                                                            | false   | No       |
| <a id="opt-tls" href="#opt-tls" title="#opt-tls">`tls`</a> | TLS configuration.<br />Can be an empty value(`{}`):<br />A self signed is generated in such a case<br />(or the [default certificate](../tls/tlsstore.md) is used if it is defined.)                                                                                                                                                                                                   |         | No       |
| <a id="opt-routesn-services" href="#opt-routesn-services" title="#opt-routesn-services">`routes[n].`<br />`services`</a> | List of any combination of [TraefikService](./traefikservice.md) and [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). <br /> Exhaustive list of option in the [`Service`](./service.md#configuration-options) documentation.                                                                                                              |         | No       |
| <a id="opt-tls-secretName" href="#opt-tls-secretName" title="#opt-tls-secretName">`tls.secretName`</a> | [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the same namesapce as the `IngressRoute`)                                                                                                                                                                                                                             | ""      | No       |
| <a id="opt-tls-options-name" href="#opt-tls-options-name" title="#opt-tls-options-name">`tls.`<br />`options.name`</a> | Name of the [`TLSOption`](../tls/tlsoption.md) to use.<br />More information [here](#tls-options).                                                                                                                                                                                                                                                                                      | ""      | No       |
| <a id="opt-tls-options-namespace" href="#opt-tls-options-namespace" title="#opt-tls-options-namespace">`tls.`<br />`options.namespace`</a> | Namespace of the [`TLSOption`](../tls/tlsoption.md) to use.                                                                                                                                                                                                                                                                                                                             | ""      | No       |
| <a id="opt-tls-certResolver" href="#opt-tls-certResolver" title="#opt-tls-certResolver">`tls.certResolver`</a> | Name of the [Certificate Resolver](../../../../install-configuration/tls/certificate-resolvers/overview.md) to use to generate automatic TLS certificates.                                                                                                                                                                                                                       | ""      | No       |
| <a id="opt-tls-domains" href="#opt-tls-domains" title="#opt-tls-domains">`tls.domains`</a> | List of domains to serve using the certificates generates (one `tls.domain`= one certificate).<br />More information in the [dedicated section](../../../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition).                                                                                                                                          |         | No       |
| <a id="opt-tls-domainsn-main" href="#opt-tls-domainsn-main" title="#opt-tls-domainsn-main">`tls.`<br />`domains[n].main`</a> | Main domain name                                                                                                                                                                                                                                                                                                                                                                 | ""      | Yes      |
| <a id="opt-tls-domainsn-sans" href="#opt-tls-domainsn-sans" title="#opt-tls-domainsn-sans">`tls.`<br />`domains[n].sans`</a> | List of alternative domains (SANs)                                                                                                                                                                                                                                                                                                                                               |         | No       |


### Middleware

- You can attach a list of [middlewares](../../../http/middlewares/overview.md) 
to each HTTP router.
- The middlewares will take effect only if the rule matches, and before forwarding
the request to the service.
- Middlewares are applied in the same order as their declaration in **router**.
- In Kubernetes, the option `middleware` allow you to attach a middleware using its
name and namespace (the namespace can be omitted when the Middleware is in the 
same namespace as the IngressRoute)

??? example "IngressRoute attached to a few middlewares"

    ```yaml 
    apiVersion: traefik.io/v1alpha1
    kind: IngressRoute
    metadata:
      name: my-app
      namespace: apps

    spec:
      entryPoints:
        - websecure
      routes:
      - match: Host(`example.com`)
        kind: Rule
        middlewares:
        # same namespace as the IngressRoute
        - name: middleware01
        # default namespace
        - name: middleware02
          namespace: apps
        # Other namespace
        - name: middleware03
          namespace: other-ns
        services:
        - name: whoami
          port: 80
    ```

??? abstract "routes.services.kind"

    As the field `name` can reference different types of objects, use the field `kind` to avoid any ambiguity.
    The field `kind` allows the following values:

    - `Service` (default value): to reference a [Kubernetes Service](https://kubernetes.io/docs/concepts/services-networking/service/)
    - `TraefikService`: to reference an object [`TraefikService`](../http/traefikservice.md)


### TLS Options

The `options` field enables fine-grained control of the TLS parameters.
It refers to a [TLSOption](../tls/tlsoption.md) and will be applied only if a `Host` 
rule is defined.

#### Server Name Association

A TLS options reference is always mapped to the host name found in the `Host` 
part of the rule, but neither to a router nor a router rule.
There could also be several `Host` parts in a rule.
In such a case the TLS options reference would be mapped to as many host names.

A TLS option is picked from the mapping mentioned above and based on the server 
name provided during the TLS handshake, 
and it all happens before routing actually occurs.

In the case of domain fronting,
if the TLS options associated with the Host Header and the SNI are different then
Traefik will respond with a status code `421`.

#### Conflicting TLS Options

Since a TLS options reference is mapped to a host name, if a configuration introduces
a situation where the same host name (from a `Host` rule) gets matched with two 
TLS options references, a conflict occurs, such as in the example below.

??? example

    ```yaml tab="IngressRoute01"
      apiVersion: traefik.io/v1alpha1
      kind: IngressRoute
      metadata:
        name: IngressRoute01
        namespace: apps

      spec:
        entryPoints:
          - foo
        routes:
        - match: Host(`example.net`)
          kind: Rule
        tls:
          options: foo
          ...

    ```

    ```yaml tab="IngressRoute02"
      apiVersion: traefik.io/v1alpha1
      kind: IngressRoute
      metadata:
        name: IngressRoute02
        namespace: apps

      spec:
        entryPoints:
          - foo
        routes:
        - match: Host(`example.net`)
          kind: Rule
        tls:
          options: bar
        ...
    ```

If that happens, both mappings are discarded, and the host name
(`example.net` in the example) for these routers gets associated with
 the default TLS options instead.

### Multi-Layer Routing with IngressRoutes

Multi-layer routing allows creating hierarchical relationships between IngressRoutes,
where parent IngressRoutes can apply middleware before child IngressRoutes make routing decisions.

This is particularly useful for authentication-based routing,
where a parent IngressRoute authenticates requests and adds context (e.g., user roles as headers),
and child IngressRoutes route based on that context.

When a child IngressRoute references a parent IngressRoute with multiple routes,
**all** parent routers then become parents of **all** child routers.

!!! info "Comprehensive Multi-Layer Routing Documentation"

    For detailed information about multi-layer routing concepts, validation rules, and use cases, see the dedicated [Multi-Layer Routing](../../../../routing-configuration/http/routing/multi-layer-routing.md) page.

#### Configuration Requirements

### Root IngressRoutes

- Have no `parentRefs` (top of the hierarchy)
- **Can** have `entryPoints`, `tls`, and `observability` configuration
- Can be either parent IngressRoutes (with children) or standalone IngressRoutes (with service)

### Intermediate IngressRoutes

- Reference their parent IngressRoute(s) via `parentRefs`
- Have one or more child IngressRoutes
- **Must not** have a `service` defined
- **Must not** have `entryPoints`, `tls`, or `observability` configuration

### Leaf IngressRoutes

- Reference their parent IngressRoute(s) via `parentRefs`
- **Must** have a `service` defined
- **Must not** have `entryPoints`, `tls`, or `observability` configuration

!!! warning "Cross-Namespace References"

    Cross-namespace parent references require the `allowCrossNamespace` provider option to be enabled. 
    If disabled, child IngressRoute creation will be skipped with an error logged.

#### Example: Authentication-Based Routing

??? example "Parent IngressRoute with ForwardAuth and Child IngressRoutes"

    ```yaml tab="Parent IngressRoute"
    apiVersion: traefik.io/v1alpha1
    kind: IngressRoute
    metadata:
      name: api-parent
      namespace: default
    spec:
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt
      routes:
        # Parent route with authentication - no services
        - match: Host(`api.example.com`) && PathPrefix(`/api`)
          kind: Rule
          middlewares:
            - name: auth-middleware
              namespace: default
    ---
    apiVersion: traefik.io/v1alpha1
    kind: Middleware
    metadata:
      name: auth-middleware
      namespace: default
    spec:
      forwardAuth:
        address: "http://auth-service.default.svc.cluster.local:8080/auth"
        authResponseHeaders:
          - X-User-Role
          - X-User-Name
    ```

    ```yaml tab="Child IngressRoutes"
    # Child IngressRoute for admin users
    apiVersion: traefik.io/v1alpha1
    kind: IngressRoute
    metadata:
      name: api-admin
      namespace: default
    spec:
      parentRefs:
        - name: api-parent
          namespace: default  # Optional - defaults to same namespace
      routes:
        - match: HeadersRegexp(`X-User-Role`, `admin`)
          kind: Rule
          services:
            - name: admin-service
              port: 80
    ---
    # Child IngressRoute for regular users
    apiVersion: traefik.io/v1alpha1
    kind: IngressRoute
    metadata:
      name: api-user
      namespace: default
    spec:
      parentRefs:
        - name: api-parent
      routes:
        - match: HeadersRegexp(`X-User-Role`, `user`)
          kind: Rule
          services:
            - name: user-service
              port: 80
    ```

    ```yaml tab="Services"
    apiVersion: v1
    kind: Service
    metadata:
      name: auth-service
      namespace: default
    spec:
      ports:
        - port: 8080
      selector:
        app: auth-service
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: admin-service
      namespace: default
    spec:
      ports:
        - port: 80
      selector:
        app: admin-backend
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: user-service
      namespace: default
    spec:
      ports:
        - port: 80
      selector:
        app: user-backend
    ```

    **How it works:**

    1. Request to `https://api.example.com/api/endpoint` matches the parent router
    2. `auth-middleware` (ForwardAuth) validates the request with `auth-service`
    3. `auth-service` returns 200 OK with `X-User-Role` header (e.g., `admin` or `user`)
    4. Child routers evaluate rules against the modified request (with `X-User-Role` header)
    5. Request is routed to `admin-service` or `user-service` based on the role
