---
title: "HTTP connection manager"
url: "/reference/filters/network/http-connection-manager/"
kind: "reference"
summary: "Terminal network filter that speaks HTTP, runs the HTTP filter chain and routes requests to clusters."
---

> Arion site index: [/llms.txt](/llms.txt)

# HTTP connection manager

Terminal network filter that speaks HTTP, runs the HTTP filter chain and routes requests to clusters.

| Attachment | Type URL (`@type`) | Per-route override | Build feature |
|---|---|---|---|
| Filter chain (`filters`, terminal) | `type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager` | Not applicable | None |

## What it does

The HTTP connection manager (HCM) turns the connection's byte stream into HTTP requests, runs each request through its `http_filters` chain, and routes it with an inline `route_config` or a route configuration fetched over RDS. It is a terminal filter: exactly one HCM or [TCP proxy](@/reference/filters/network/tcp-proxy.md) ends every filter chain, and nothing may follow it.

## Minimal configuration

The fragment sits under `filter_chains[].filters` of a listener:

```yaml,arion=fragment
- name: http_gateway
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
    codec_type: AUTO
    http_filters:
      - name: envoy.filters.http.router
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
          start_child_span: false
    route_config:
      name: local_route
      virtual_hosts:
        - name: backend
          domains: ["*"]
          routes:
            - match: { prefix: "/" }
              route: { cluster: api }
```

## Fields

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `codec_type` | enum | No | `AUTO` | `AUTO`, `HTTP1` or `HTTP2`. `HTTP3` is rejected. |
| `stat_prefix` | string | No | — | Accepted for Envoy compatibility but ignored; Arion logs a warning. |
| `http_filters` | list | Yes | — | The HTTP filter chain. Must be non-empty and end with the [router](@/reference/filters/http/router.md), which cannot be disabled. |
| `route_config` / `rds` | oneof | Yes | — | Inline route configuration, or RDS (see below). |
| `request_timeout` | duration | No | unset | Overall timeout for a downstream request. |
| `access_log` | list | No | empty | File, stdout or stderr access loggers; see [access logs](@/docs/observe/access-logs.md). |
| `upgrade_configs` | list | No | empty | Enabled protocol upgrades. Only `websocket` is supported; `connect` is rejected. |
| `use_remote_address` | bool | No | `false` | Use the direct peer address instead of `x-forwarded-for` when determining the client address. |
| `xff_num_trusted_hops` | uint32 | No | `0` | Number of trusted proxy hops counted from the right of `x-forwarded-for`. |
| `skip_xff_append` | bool | No | `false` | Do not append the client address to `x-forwarded-for`. |
| `generate_request_id` | bool | No | `true` | Generate `x-request-id` when absent. |
| `preserve_external_request_id` | bool | No | `false` | Keep an externally supplied `x-request-id` instead of replacing it. |
| `always_set_request_id_in_response` | bool | No | `false` | Echo `x-request-id` in the response even when the client did not send one. |
| `tracing` | object | No | unset | Trace sampling and exporter; see below. |
| `early_header_mutation_extensions` | list | No | empty | `header_mutation` extensions applied before routing. |

Any other Envoy HCM field is unsupported: setting one makes Arion refuse to start, which is the [compatibility promise](@/docs/concepts/envoy-compatibility.md).

### Route specifier

`route_config` embeds a full route table (documented in the [routes reference](@/reference/resources/routes.md)). `rds` subscribes to it over xDS instead; only the aggregated channel is supported:

```yaml,arion=fragment
rds:
  route_config_name: my_routes
  config_source:
    ads: {}
```

### Tracing

`tracing` accepts `client_sampling`, `random_sampling` and `overall_sampling` (percentages, 0–100), `verbose`, `max_path_tag_length`, `spawn_upstream_span`, and a `provider` whose `typed_config` must be `type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig` with a `grpc_service` and `service_name`. See [tracing](@/docs/observe/tracing.md).

## Ordering and interactions

Within a filter chain the HCM runs after network RBAC, rate limit and connection limit filters have admitted the connection. Its `http_filters` then run in list order per request, ending in the router; the response traverses filters that act on responses in reverse.
