---
title: "TCP proxy"
url: "/reference/filters/network/tcp-proxy/"
kind: "reference"
summary: "Terminal network filter that forwards the raw byte stream to an upstream cluster."
---

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

# TCP proxy

Terminal network filter that forwards the raw byte stream to an upstream cluster.

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

## What it does

The TCP proxy forwards the connection's bytes verbatim to an upstream cluster — no HTTP parsing, no request-level filters. Use it for any non-HTTP protocol, or for TLS passthrough where the filter chain is selected by SNI and the encrypted stream is relayed untouched. Like the [HTTP connection manager](@/reference/filters/network/http-connection-manager.md), it is a terminal filter: exactly one ends each filter chain.

## Minimal configuration

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

```yaml,arion=fragment
- name: tcp
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
    cluster: backend
```

## Fields

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `cluster` / `weighted_clusters` | oneof | Yes | — | Target cluster, or a weighted split (see below). |
| `stat_prefix` | string | No | — | Accepted for Envoy compatibility but ignored; Arion logs a warning. |
| `access_log` | list | No | empty | Connection access loggers; see [access logs](@/docs/observe/access-logs.md). |

All other Envoy TCP proxy fields — idle timeouts, `max_connect_attempts`, hash policies, tunneling — are unsupported, and a configuration that sets them is refused at startup.

### Weighted clusters

Traffic can be split across clusters by weight; each entry needs a `name` and a `weight` greater than zero:

```yaml,arion=fragment
weighted_clusters:
  clusters:
    - name: backend-v1
      weight: 90
    - name: backend-v2
      weight: 10
```

## Ordering and interactions

The TCP proxy runs after network [RBAC](@/reference/filters/network/rbac.md), [rate limit](@/reference/filters/network/rate-limit.md) and [connection limit](@/reference/filters/network/connection-limit.md) filters have admitted the connection; declaring any of them after the TCP proxy in the same chain is a startup error. When the listener has a TLS inspector, `filter_chain_match.server_names` routes different SNIs to different TCP proxy chains — a pattern the [Route TCP at L4](@/guides/proxy/route-tcp-at-l4.md) guide extends in its production notes.
