---
description: Connect services and devices with post-quantum encrypted private networking through Cloudflare.
title: Cloudflare Mesh
image: https://developers.cloudflare.com/mesh/og.png?v=8d5812809f56150a
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Cloudflare Mesh

Last updated Sep 16, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Connect services and devices with post-quantum encrypted private networking through Cloudflare.

Cloudflare Mesh gives every enrolled server, laptop, and phone a private Mesh IP. Participants can communicate by IP over TCP, UDP, or ICMP, including device-to-device connections that do not require customer-managed networking infrastructure.

Mesh nodes run the [Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/) in headless mode on Linux. They can also advertise routes to make private subnets and hostnames reachable from other Mesh participants.

The Mesh participant table lists nodes and enrolled client devices together. You can search for devices, filter by participant type or status, and open a device's Zero Trust details page. If one participant source fails, participants from the other source remain available while you retry the request.

![The Mesh network map in the Cloudflare dashboard showing nodes and devices connected through Cloudflare](https://developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=2070,height=875,format=webp/_astro/mesh-network-map.CED6jNHK.gif)

Note

Cloudflare Mesh was previously known as WARP Connector and peer-to-peer connectivity. Existing WARP Connectors are now called Mesh nodes. Existing deployments continue to work without migration.

For details about how Mesh works, protocol requirements, and Mesh IP assignment, refer to [Concepts](https://developers.cloudflare.com/mesh/concepts/).

## Use cases

- Connect enrolled devices to each other by private IP.
- Provide bidirectional connectivity between servers, cloud networks, and sites.
- Route traffic to devices that cannot run the Cloudflare One Client.
- Preserve long-lived TCP connections for databases, replication, ERP systems, and remote administration.

## Get started

### [Set up Cloudflare Mesh](https://developers.cloudflare.com/mesh/get-started/)

Configure your account and connect your first participant.

### [Understand Mesh](https://developers.cloudflare.com/mesh/concepts/)

Learn how participants, Mesh IPs, routing, and policies work.

### [Explore features](https://developers.cloudflare.com/mesh/features/)

Configure routes and high availability for Mesh nodes.

### [Follow a guide](https://developers.cloudflare.com/mesh/guides/)

Connect devices, servers, and sites, or deploy Mesh in containers.

## Mesh vs. Cloudflare Tunnel

Use Mesh when participants need bidirectional private IP connectivity or when a workload requires stable, long-lived connections. Use [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/) when you want to publish specific applications, hostnames, or IP routes through an outbound-only connector.

For a detailed comparison, refer to [How Cloudflare Mesh works](https://developers.cloudflare.com/mesh/concepts/#mesh-vs-tunnel).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/mesh/#page","headline":"Cloudflare Mesh","description":"Connect services and devices with post-quantum encrypted private networking through Cloudflare.","url":"https://developers.cloudflare.com/mesh/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/og.png?v=8d5812809f56150a","dateModified":"2026-09-16","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Set up Cloudflare Mesh and connect your first server, laptop, or phone to your private network.
title: Get started
image: https://developers.cloudflare.com/mesh/get-started/og.png?v=e83d28b009fffd35
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Get started

Last updated Sep 16, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/get-started/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Set up Cloudflare Mesh so your devices and servers can reach each other by private IP.

## Prerequisites

- A [Cloudflare account ↗︎](https://dash.cloudflare.com/sign-up)
- A [Zero Trust organization](https://developers.cloudflare.com/cloudflare-one/setup/#2-create-a-zero-trust-organization) with an active subscription, including the Free plan
- A laptop or phone to connect as a client device
- (Optional) A Linux server to deploy a Mesh node<details><summary>

  Linux server requirements</summary>

  | **OS version** | RHEL 9 <sup><a href="#user-content-fn-1">1</a></sup>, RHEL 10, Debian 12, Debian 13, Fedora 43, Fedora 44, Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, Ubuntu 26.04 LTS |
  | --- | --- |
  | **Processor** | AMD64 / x86-64 or ARM64 / AArch64 |
  | **vCPU** | 3 minimum, 4 recommended |
  | **RAM without a desktop** | 1 GB minimum, 2 GB recommended (for example, Ubuntu Server) |
  | **RAM with a desktop** | 4 GB minimum, 8 GB recommended (for example, Ubuntu GNOME) |
  | **Disk space** | 250 MiB minimum, 500 MiB recommended |
  | **Network interface type** | Wi-Fi or LAN |
  | **MTU** | 1381 bytes recommended <sup><a href="#user-content-fn-2">2</a></sup> | ## Footnotes<a href="#footnote-label"></a>
  1. On RHEL 9 and later, enable the <a href="https://docs.fedoraproject.org/en-US/epel/">Extra Packages for Enterprise Linux (EPEL) ↗︎</a> repository before installing <code>cloudflare-warp</code>. EPEL provides dependencies required by the client UI. For the RHEL commands, refer to <a href="https://docs.fedoraproject.org/en-US/epel/getting-started/">Getting started with EPEL ↗︎</a>. <a href="#user-content-fnref-1">↩</a>
  2. Minimum 1281 bytes with <a href="https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/mdm-deployment/path-mtu-discovery/">Path MTU Discovery</a> <a href="#user-content-fnref-2">↩</a></details>

Mesh nodes are optional

  Client-to-client connectivity works without any Mesh nodes. Two enrolled laptops can reach each other directly by Mesh IP. Mesh nodes are for running the client in headless mode on a server — either to make that server reachable by its Mesh IP, or to [route traffic to a private subnet](https://developers.cloudflare.com/mesh/features/routes/) behind it. Configure the [required account settings](#required-account-settings) before connecting participants. You can use the dashboard wizard, APIs, or Terraform.

Cloudflare Mesh requires that the Mesh node's [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) is configured to use [MASQUE](https://developers.cloudflare.com/mesh/concepts/#protocol-requirement). Hostname routes, IPv6 CIDR routes, and high availability do not work if the device profile uses WireGuard instead.

## Choose a participant type

Choose an enrollment method based on what you want to connect:

| Goal | Participant type | Enrollment method | Browser required |
| --- | --- | --- | --- |
| Run a service or route a subnet from Linux | [Mesh node](#1-configure-mesh) | Connector token | No |
| Connect an unattended Windows, macOS, or Linux device | [Headless client device](https://developers.cloudflare.com/mesh/guides/connect-client-devices/#headless-windows-macos-and-linux-devices) | Service token and managed deployment parameters | No |
| Connect a user device with identity | [Client device](#2-connect-a-client-device) | Interactive identity provider enrollment | Yes |

## 1. Configure Mesh

Choose the dashboard wizard or API and Terraform resources.

The setup wizard [configures your account for Mesh networking](#required-account-settings) and optionally guides you through creating a Mesh node. This is a one-time setup.

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select **Add participant** > **Add node**.
3. Enter a name for your node (for example, `web-server` or `staging-db`).
4. Select **Create node**.
5. Select **Linux**, **Kubernetes**, **Docker Compose**, or **Docker CLI**.
6. Follow the installation instructions for your selected method. The dashboard masks the node token but includes it when required by a copied command. Docker Compose configurations and Kubernetes manifests reference a secret instead of containing the token.
7. (Optional) If you are not ready to install the node, select **I'll connect later**. You can install the node from its detail page later.
8. If you installed the node, wait for it to connect and select **Continue**.

If you installed the node, it should appear as **Online** on the Mesh overview page along with its assigned **Mesh IP**. If the node does not come online, refer to [Troubleshooting](#troubleshooting).

The dashboard wizard is not required. After account bootstrap, APIs and Terraform can automate the supported Mesh resources. You will need your [account ID](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/), Zero Trust team name, `jq`, and an [API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) with permissions for the resources you configure.

Initial API token

You must create the initial API token in the dashboard. An authorized token can [create subsequent user-owned or account-owned tokens through the API](https://developers.cloudflare.com/fundamentals/api/how-to/create-via-api/).

Before continuing, configure every item in [Required account settings](#required-account-settings). The examples in this section configure the Mesh node device profile, node, and connector token. You must configure device enrollment and global settings separately. **Allow all Cloudflare One traffic to reach enrolled devices** and the ICMP Gateway proxy require dashboard configuration.

Before connecting a node, create a safe Include-mode profile. This request requires the `Zero Trust Write` permission. It matches Mesh nodes, uses MASQUE in Traffic and DNS mode, and routes only the Mesh IP range through Cloudflare:

```bash
set -euo pipefail

PROFILE_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/devices/policy" \
		--request POST \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
		--header "Content-Type: application/json" \
		--data "$(jq -n \
			--arg match "identity.email == \"warp_connector@$TEAM_NAME.cloudflareaccess.com\"" \
			'{
				name: "Cloudflare Mesh nodes",
				description: "Route Mesh IP traffic through Cloudflare",
				enabled: true,
				precedence: 100,
				match: $match,
				service_mode_v2: {mode: "warp"},
				tunnel_protocol: "masque",
				include: [{address: "100.96.0.0/12", description: "Cloudflare Mesh IPs"}]
			}')"
)

jq -e '.success == true and (.result.id | type == "string")' \
	<<< "$PROFILE_RESPONSE" > /dev/null
PROFILE_ID=$(jq -r '.result.id' <<< "$PROFILE_RESPONSE")
```

Set `ACCOUNT_ID`, `TEAM_NAME`, and `CLOUDFLARE_API_TOKEN` in the shell before running the command. Use an unused `precedence` value that places this profile before broader profiles. Do not add an `exclude` field. A device profile cannot contain both `include` and `exclude`.

The API response uses the standard `success`, `errors`, `messages`, and `result` fields. A non-2xx response causes `curl` to fail. A response with `success: false` or without `result.id` causes `jq` to fail. Do not continue until the command returns zero and `PROFILE_ID` is set.

The following requests require an API token with either `Cloudflare One Connectors Write` or `Cloudflare One Connector: WARP Write` permission. To create a Mesh node and retrieve its connector token:

```bash
set -euo pipefail

NODE_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/warp_connector" \
		--request POST \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
		--header "Content-Type: application/json" \
		--data '{"name":"web-server"}'
)

jq -e '.success == true and (.result.id | type == "string")' \
	<<< "$NODE_RESPONSE" > /dev/null
NODE_ID=$(jq -r '.result.id' <<< "$NODE_RESPONSE")

TOKEN_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/warp_connector/$NODE_ID/token" \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
)

MESH_NODE_TOKEN=$(jq -er \
	'select(.success == true) | .result | select(type == "string" and length > 0)' \
	<<< "$TOKEN_RESPONSE")
```

The commands stop on an HTTP or API error. Do not continue until they return zero and set `NODE_ID` and `MESH_NODE_TOKEN`. If token retrieval fails after node creation, retry only the token request with the existing `NODE_ID`. Do not rerun the node creation request.

Install the node and replace `<TOKEN>` with the value of `MESH_NODE_TOKEN`:

IP forwarding is not required to reach the node by its Mesh IP. If the node will advertise [CIDR routes](https://developers.cloudflare.com/mesh/features/routes/), enable persistent forwarding before connecting it:

```sh
printf 'net.ipv4.ip_forward = 1\nnet.ipv6.conf.all.forwarding = 1\nnet.ipv6.conf.all.accept_ra = 2\n' | sudo tee /etc/sysctl.d/99-zzz-cloudflare-warp-connector.conf &&
sudo sysctl --system
```

```sh
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg &&
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(. /etc/os-release && echo $VERSION_CODENAME) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list &&
sudo apt-get update -qq && sudo apt-get install -y -qq cloudflare-warp
```

```sh
sudo warp-cli --accept-tos connector new <TOKEN> && sudo warp-cli --accept-tos connect
```

On RHEL 9 and later, enable the Extra Packages for Enterprise Linux (EPEL) repository before installing `cloudflare-warp`. EPEL provides dependencies required by the Cloudflare One Client UI. Turn on CodeReady Builder, then install the EPEL release package for your RHEL version:

```sh
sudo subscription-manager repos --enable codeready-builder-for-rhel-$(rpm -E %rhel)-$(arch)-rpms &&
sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E %rhel).noarch.rpm
```

On Rocky Linux, AlmaLinux, and other RHEL-compatible distributions, run `sudo dnf config-manager --set-enabled crb && sudo dnf install -y epel-release` instead. For details, refer to [Run Mesh on Linux](https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/#rhel).

Then install the package:

```sh
curl -fsSL https://pkg.cloudflareclient.com/cloudflare-warp-ascii.repo | sudo tee /etc/yum.repos.d/cloudflare-warp.repo &&
sudo dnf install -y cloudflare-warp
```

```sh
sudo warp-cli --accept-tos connector new <TOKEN> && sudo warp-cli --accept-tos connect
```

You can also manage nodes with the [`cloudflare_zero_trust_tunnel_warp_connector` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_warp_connector) resource. Use [`cloudflare_zero_trust_tunnel_warp_connector_config` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_warp_connector_config) to manage node configuration.

## 2. Connect a client device

Use the Add device workflow to find the Cloudflare One Client installer and organization name for a laptop or phone:

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select **Add participant** > **Add device**.
3. Select the device platform and use the provided link or QR code to install the Cloudflare One Client.
4. Open the client and select **Cloudflare Zero Trust** when prompted for a connection type.
5. Enter the organization name displayed in the Mesh dashboard and complete authentication.

The workflow does not enroll the device or verify connectivity. After the Cloudflare One Client displays **Connected**, test connectivity as described in [Connect two devices](https://developers.cloudflare.com/mesh/guides/connect-client-devices/#verify-connectivity).

## 3. Test connectivity

From a Windows, macOS, or Linux client device, verify TCP connectivity to a Mesh node or another enrolled device. For example, test SSH:

```sh
nc -vz <MESH-IP> 22
```

```powershell
Test-NetConnection <MESH-IP> -Port 22
```

Replace `<MESH-IP>` with the Mesh IP shown on the Mesh overview page. Replace port `22` with the port used by your service. You can test HTTP services from a mobile browser. A connected client or healthy connector status does not verify peer connectivity. Verify the application protocol you intend to use. If you turned on the ICMP Gateway proxy, you can also run `ping <MESH-IP>` as a diagnostic check.

## Logs

Mesh traffic appears in [Gateway network logs](https://developers.cloudflare.com/cloudflare-one/insights/logs/dashboard-logs/gateway-logs/#network-logs) with **Mesh** as the **Traffic Source** when a Mesh node sends it, and as the **Traffic Destination** when it is routed to a Mesh node. Client device traffic appears under the enrolled user's identity.

For session-level detail, use [Zero Trust Network Session Logs](https://developers.cloudflare.com/logs/logpush/logpush-job/datasets/account/zero_trust_network_sessions/). Mesh sessions report `OnrampType` or `Offramp` as `MESH`, and `DestinationReplicaID` identifies which replica of a [highly available](https://developers.cloudflare.com/mesh/features/high-availability/) node served the session.

## Required account settings

The dashboard wizard configures the following Cloudflare One settings automatically for new deployments. Non-wizard deployments must configure the same settings:

| Setting | What it does |
| --- | --- |
| [Device enrollment policy](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/device-enrollment/) | Allows devices to enroll into your Cloudflare One account using email-based [one-time PIN](https://developers.cloudflare.com/cloudflare-one/integrations/identity-providers/one-time-pin/). Only created if you do not already have an existing device enrollment policy in your account. |
| [Device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) | Creates a profile configured with [Split Tunnels](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/split-tunnels/) in **Include mode**, so only Mesh traffic routes through Cloudflare. This prevents disrupting existing network connectivity on your server. Only created if you do not already have an active Mesh node (formerly WARP Connector) in your account. |
| [Allow all Cloudflare One traffic to reach enrolled devices](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#allow-all-cloudflare-one-traffic-to-reach-enrolled-devices) and [Assign a unique IP address to each device](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#assign-a-unique-ip-address-to-each-device) | Enables device-to-device connectivity for Mesh networking. |
| [Gateway proxy](https://developers.cloudflare.com/cloudflare-one/traffic-controls/proxy/) | Enables TCP and UDP proxying for Mesh services. ICMP proxying is optional and supports diagnostics such as `ping` and `traceroute`. |

For automated deployments, the device profile documentation includes API and Terraform examples. Set `service_mode_v2 = { mode = "warp" }`, replace the generic example's `wireguard` protocol with `tunnel_protocol = "masque"`, and configure Split Tunnels to route `100.96.0.0/12` through Cloudflare. Match Mesh nodes with `identity.email == "warp_connector@<TEAM_NAME>.cloudflareaccess.com"`, and place this profile before broader profiles. The device enrollment documentation includes the Terraform enrollment-policy flow.

### Automated settings

The [`cloudflare_zero_trust_device_settings` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_device_settings) resource supports unique device IPs and the TCP and UDP Gateway proxies:

```tf
resource "cloudflare_zero_trust_device_settings" "mesh" {
	account_id                        = var.cloudflare_account_id
	use_zt_virtual_ip                 = true
	gateway_proxy_enabled             = true
	gateway_udp_proxy_enabled         = true
}
```

### Human-only settings

The Terraform resource does not configure **Allow all Cloudflare One traffic to reach enrolled devices** or the ICMP Gateway proxy. Before connecting participants, turn on enrolled-device reachability in the dashboard. Turn on ICMP only if you require `ping`, `traceroute`, or another ICMP-based workflow.

### Existing Cloudflare One accounts

If your account already has a Cloudflare One deployment, the setup wizard will not overwrite your existing configuration. Verify the following settings are enabled for Mesh to work:

- **Device enrollment** — At least one [enrollment rule](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/device-enrollment/) must exist so that devices and nodes can register with your account.
- **Device profile for Mesh nodes** — Your Mesh nodes need a [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/split-tunnels/) that routes the Mesh IP range ( `100.96.0.0/12`) through Cloudflare. In Include mode, add the Mesh range. In Exclude mode, verify that no custom or legacy entry contains the Mesh range.
- **Mesh connectivity** — In your device profile settings, enable [Allow all Cloudflare One traffic to reach enrolled devices](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#allow-all-cloudflare-one-traffic-to-reach-enrolled-devices).
- **Unique device IPs** — Enable [Assign a unique IP address to each device](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#assign-a-unique-ip-address-to-each-device) so that each participant gets a routable Mesh IP.
- **Client mode** — Mesh nodes must run in [Traffic and DNS mode](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/modes/). DNS-only or proxy-only modes are not supported.
- **Traffic proxying** — Turn on the [Gateway proxy](https://developers.cloudflare.com/cloudflare-one/traffic-controls/proxy/) for the protocols you use. TCP and UDP carry Mesh services. ICMP supports diagnostic tools such as `ping` and `traceroute`.

## Troubleshooting

- **Node shows as Offline** — On the server, run `warp-cli status`. If the output does not show `Status update: Connected`:
  - Run `warp-cli connect`.
  - If your private network uses a firewall to restrict Internet traffic, ensure that it allows the [WARP ports and IPs](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/firewall/).
  - Review your [WARP daemon logs](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/troubleshooting/diagnostic-logs/) for information about why the connection is failing.
- **Client device cannot reach Mesh IPs** — Verify that your Split Tunnel configuration routes the Mesh IP range ( `100.96.0.0/12`) through Cloudflare. For details, refer to [Connect two devices](https://developers.cloudflare.com/mesh/guides/connect-client-devices/).
- **Windows firewall blocks Mesh traffic** — Windows Firewall blocks inbound traffic from `100.96.0.0/12` by default. Add a firewall rule that allows incoming requests from this range for your desired protocols and ports.

For general client issues, refer to [Troubleshoot the Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/troubleshooting/).

For unreachable Mesh IPs, routed subnets, and one-way site traffic, refer to [Troubleshoot Cloudflare Mesh connectivity](https://developers.cloudflare.com/mesh/troubleshooting/).

## Next steps

- [**Connect two devices**](https://developers.cloudflare.com/mesh/guides/connect-client-devices/) — Enroll two devices and verify private connectivity between them.
- [**Run Mesh on Linux**](https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/) — Install a Mesh node on Debian, Ubuntu, or RHEL, with each command explained.
- [**Run in Docker / Kubernetes**](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/) — Deploy a Mesh node as a Docker container for Docker Compose, Kubernetes, and CI/CD pipelines.
- [**Add routes**](https://developers.cloudflare.com/mesh/features/routes/) — Make an entire subnet behind your node reachable (databases, printers, other servers).
- [**Enable high availability**](https://developers.cloudflare.com/mesh/features/high-availability/) — Run multiple replicas for production resilience.
- [**Tips and best practices**](https://developers.cloudflare.com/mesh/best-practices/) — Cloud VPC configuration, updating the client, running alongside cloudflared.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/get-started/#page","headline":"Get started","description":"Set up Cloudflare Mesh and connect your first server, laptop, or phone to your private network.","url":"https://developers.cloudflare.com/mesh/get-started/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/get-started/og.png?v=e83d28b009fffd35","dateModified":"2026-09-16","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Learn how Cloudflare Mesh connects participants, assigns private IPs, routes traffic, and differs from Cloudflare Tunnel.
title: How Cloudflare Mesh works
image: https://developers.cloudflare.com/mesh/concepts/og.png?v=c018353ab5f2cff6
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# How Cloudflare Mesh works

Last updated Sep 16, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/concepts/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare Mesh is a private network for services and devices in your Cloudflare account. It gives each enrolled participant a private address and carries traffic between participants through Cloudflare.

Participants can be Linux servers, laptops, phones, or desktops. They communicate over TCP, UDP, or Internet Control Message Protocol (ICMP) without public IP addresses or services exposed to the public Internet. Host firewalls on each participant still control which Mesh traffic it accepts.

## The connection starts with the Cloudflare One Client

*Connect each participant to Cloudflare with the same client.*

Every participant runs the [Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/), which keeps an encrypted connection to Cloudflare open for Mesh traffic. A **Mesh node** runs the client in headless mode on a Linux server, virtual machine, or container. A **client device** runs the same software with a user interface on a laptop, phone, or desktop.

Cloudflare assigns each participant a Mesh IP from `100.96.0.0/12`, a [carrier-grade NAT range ↗︎](https://datatracker.ietf.org/doc/html/rfc6598) that avoids common private ranges such as `10.0.0.0/8`. Other Cloudflare One documentation calls these [device IPs](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-ips/), and you can configure a custom subnet if the default conflicts with your network.

Any participant can start traffic to another participant's Mesh IP, so device-to-device, device-to-server, and server-to-server connections all work. Client-to-client connectivity does not require a Mesh node.

Not connected

Connect node

Your account's Mesh network

Mesh node

Client device

Cloudflare100.96.0.1100.96.0.10

Not connected

All traffic passes through Cloudflare, so [Gateway network policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/), [device posture checks](https://developers.cloudflare.com/cloudflare-one/reusable-components/posture-checks/), and identity controls can govern each connection. Connectivity and access are separate: a participant can be online while policy blocks its traffic.

For setup instructions, refer to [Get started](https://developers.cloudflare.com/mesh/get-started/).

## Routes extend Mesh to private networks

*Reach resources that cannot run the Cloudflare One Client.*

A Mesh node is directly reachable through its own Mesh IP. A route makes resources behind that node reachable as well.

- **CIDR routes** send traffic for an IPv4 or IPv6 range through a node.
- **Hostname routes** send traffic for a private or public hostname through a node.

No matching route

Add routeSend request

Client

Cloudflare

Mesh node

Database · 10.0.0.50No matching route

No matching route

Return traffic must also route through the Mesh node. For more information, refer to [Routes](https://developers.cloudflare.com/mesh/features/routes/).

## Node identity and high availability

*Keep routed networks available when a node host fails.*

A Mesh node has a stable identity in your Cloudflare account. Multiple Linux hosts can register as replicas of that node and advertise the same routes. One replica is active while the others stay on standby. If the active replica disconnects, Cloudflare promotes a standby for traffic to the advertised CIDR routes.

Replica A active

Stop AAdd BSend request

Mesh node #123

Client

Cloudflare

Replica A

Replica BActiveNot added

Database · 10.0.0.50

Replica A active

High availability protects routed prefixes, not direct access to a replica's Mesh IP. For more information, refer to [High availability](https://developers.cloudflare.com/mesh/features/high-availability/).

## Protocol requirement

Mesh uses the [MASQUE](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#device-tunnel-protocol) protocol by default. Hostname routes, IPv6 CIDR routes, and high availability require MASQUE. If a Mesh node device profile uses WireGuard, only direct participant connectivity and IPv4 CIDR routes work.

## Mesh vs. Cloudflare Tunnel

Mesh and [Cloudflare Tunnel](https://developers.cloudflare.com/tunnel/) both connect private infrastructure to Cloudflare. They use different connection models:

|  | Cloudflare Mesh | Cloudflare Tunnel |
| --- | --- | --- |
| **Connection model** | Participants can initiate traffic in either direction | Clients connect to resources behind `cloudflared` |
| **Addressing** | Every participant receives a Mesh IP | Resources use published hostnames or private routes |
| **Connector** | Cloudflare One Client | `cloudflared` |
| **Primary use** | Private connectivity between devices, servers, and networks | Publishing applications or routing to private resources |

Use Mesh when participants need private IP connectivity in either direction, including long-lived connections such as database replication and remote administration. Use Tunnel to publish specific applications or route clients to resources behind an outbound-only connector.

<details>

<summary>

Coming from another mesh networking product?

</summary>

Common concepts map to Cloudflare Mesh as follows:

| Other products | Cloudflare Mesh |
| --- | --- |
| Mesh network or tailnet | Your Cloudflare account Mesh network |
| Node or peer | Mesh node or client device |
| Subnet router | Mesh node with a <a href="https://developers.cloudflare.com/mesh/features/routes/">CIDR route</a> |
| Access control list | <a href="https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/">Gateway network policies</a> and <a href="https://developers.cloudflare.com/cloudflare-one/reusable-components/posture-checks/">device posture</a> |
| Admin console | <a href="https://dash.cloudflare.com/?to=/:account/mesh">Cloudflare dashboard ↗︎</a> under **Networking** &gt; **Mesh** |

Unlike peer-to-peer products, Mesh traffic passes through Cloudflare. You manage policies, posture, and identity with Cloudflare One.

</details>

## Start building

Choose the participant or network you want to connect.

### [Set up Cloudflare Mesh](https://developers.cloudflare.com/mesh/get-started/)

Configure your account and connect your first participant.

### [Connect two devices](https://developers.cloudflare.com/mesh/guides/connect-client-devices/)

Add laptops, phones, and headless user devices.

### [Add routes](https://developers.cloudflare.com/mesh/features/routes/)

Reach private subnets and hostnames through a Mesh node.

### [Connect from Workers](https://developers.cloudflare.com/workers-vpc/examples/connect-to-cloudflare-mesh/)

Let Workers call services on your Mesh network.

## Related resources

- [Run Mesh in containers](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/): deploy a node with Docker or Kubernetes.
- [Tips and best practices](https://developers.cloudflare.com/mesh/best-practices/): plan routes, updates, and cloud deployments.
- [Reserved IP addresses](https://developers.cloudflare.com/cloudflare-one/networks/routes/reserved-ips/): review ranges reserved by Cloudflare One.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/concepts/#page","headline":"How Cloudflare Mesh works","description":"Learn how Cloudflare Mesh connects participants, assigns private IPs, routes traffic, and differs from Cloudflare Tunnel.","url":"https://developers.cloudflare.com/mesh/concepts/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/concepts/og.png?v=c018353ab5f2cff6","dateModified":"2026-09-16","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Configure routing and high availability for Cloudflare Mesh nodes.
title: Features
image: https://developers.cloudflare.com/mesh/features/og.png?v=7eb60c8c14c07de1
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Features

Last updated Sep 16, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/features/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

- [Routes](https://developers.cloudflare.com/mesh/features/routes/)
- [High availability](https://developers.cloudflare.com/mesh/features/high-availability/)

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/mesh/features/#page","headline":"Features","description":"Configure routing and high availability for Cloudflare Mesh nodes.","url":"https://developers.cloudflare.com/mesh/features/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/features/og.png?v=7eb60c8c14c07de1","dateModified":"2026-09-16","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Configure active-passive replicas to provide high availability for routed Cloudflare Mesh networks.
title: High availability
image: https://developers.cloudflare.com/mesh/features/high-availability/og.png?v=78b4108b2a8cfc72
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# High availability

Last updated Sep 16, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/features/high-availability/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

For production deployments, you can run multiple replicas of a Mesh node in active-passive mode. All replicas share the same node identity and advertise the same [routes](https://developers.cloudflare.com/mesh/features/routes/). If the active replica goes down, Cloudflare automatically promotes a standby replica.

MASQUE required

This feature requires that the [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) of the Mesh node is configured to use [MASQUE](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#device-tunnel-protocol), the default protocol for the Cloudflare One Client. It does not work if the device profile uses WireGuard instead.

## When to use high availability

High availability provides resilience for CIDR route prefixes advertised by a Mesh node. When the active replica disconnects, Cloudflare promotes a standby so that traffic to the advertised subnets continues to flow.

This means HA is useful for nodes that have routes configured — nodes acting as subnet gateways for private networks behind them. If a node is only used for direct Mesh IP connectivity (no routes), HA has limited benefit because the node's Mesh IP is tied to the individual replica.

High availability does not spread traffic across replicas, because only one replica is active at a time. To distribute traffic across several servers, health-check each server, or fail over between sites (for example, from a Cloudflare WAN site to a Mesh site), use a [private load balancer](https://developers.cloudflare.com/cloudflare-one/networks/load-balancing/). Within a virtual network, a CIDR can be assigned to only one tunnel or Mesh node, so endpoints behind different nodes need different IP addresses or different [virtual networks](https://developers.cloudflare.com/cloudflare-one/networks/virtual-networks/).

## How it works

When you create a Mesh node with high availability enabled, Cloudflare generates a single token for that node. You install the Cloudflare One Client on multiple Linux hosts using this token. Each host registers as a replica of the same node.

- All replicas advertise the same CIDR routes.
- One replica is active at a time. The others are passive standby.
- If the active replica disconnects, Cloudflare automatically promotes a passive replica.
- Failover is handled by Cloudflare's network.

```
flowchart LR
  subgraph replicas["Mesh node: web-server"]
    R1["Replica 1 <br> (active)"]
    R2["Replica 2 <br> (standby)"]
    R3["Replica 3 <br> (standby)"]
  end
  CF((Cloudflare)) <--> R1
  CF -. failover .-> R2
  CF -. failover .-> R3
  client["Client device"] <--> CF

```

## Create a node with high availability

When you create a Mesh node through the dashboard, high availability is enabled by default. To create a new node:

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select **Add participant** > **Add node**.
3. Follow the setup wizard. The node is created with HA enabled automatically.
4. Select an installation method and follow the displayed instructions.

To create a node with high availability via the API, set `ha: true` in the request body:

```sh
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/warp_connector" \
  -H "Authorization: Bearer {api_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web-server",
    "ha": true
  }'
```

The response includes a `token` field. Use this token to register replicas.

## Add replicas

To add a replica to an existing high-availability node, install the Cloudflare One Client on a new Linux host and register it using the same node token.

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select your Mesh node.
3. Select **Add a replica**.
4. A dialog shows the install commands and the node's token.
5. On a new Linux host, run the install commands shown in the dialog.

<details>

<summary>

Installation commands

</summary>

IP forwarding is not required to reach the node by its Mesh IP. If the node will advertise <a href="https://developers.cloudflare.com/mesh/features/routes/">CIDR routes</a>, enable persistent forwarding before connecting it:

```sh
printf 'net.ipv4.ip_forward = 1\nnet.ipv6.conf.all.forwarding = 1\nnet.ipv6.conf.all.accept_ra = 2\n' | sudo tee /etc/sysctl.d/99-zzz-cloudflare-warp-connector.conf &&
sudo sysctl --system
```

```sh
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg &&
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(. /etc/os-release && echo $VERSION_CODENAME) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list &&
sudo apt-get update -qq && sudo apt-get install -y -qq cloudflare-warp
```

```sh
sudo warp-cli --accept-tos connector new <TOKEN> && sudo warp-cli --accept-tos connect
```

On RHEL 9 and later, enable the Extra Packages for Enterprise Linux (EPEL) repository before installing <code>cloudflare-warp</code>. EPEL provides dependencies required by the Cloudflare One Client UI. Turn on CodeReady Builder, then install the EPEL release package for your RHEL version:

```sh
sudo subscription-manager repos --enable codeready-builder-for-rhel-$(rpm -E %rhel)-$(arch)-rpms &&
sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E %rhel).noarch.rpm
```

On Rocky Linux, AlmaLinux, and other RHEL-compatible distributions, run <code>sudo dnf config-manager --set-enabled crb &amp;&amp; sudo dnf install -y epel-release</code> instead. For details, refer to <a href="https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/#rhel">Run Mesh on Linux</a>.

Then install the package:

```sh
curl -fsSL https://pkg.cloudflareclient.com/cloudflare-warp-ascii.repo | sudo tee /etc/yum.repos.d/cloudflare-warp.repo &&
sudo dnf install -y cloudflare-warp
```

```sh
sudo warp-cli --accept-tos connector new <TOKEN> && sudo warp-cli --accept-tos connect
```

</details>

1. Retrieve the node's token:

   ```sh
   curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/warp_connector/{node_id}/token" \
   	-H "Authorization: Bearer {api_token}"
   ```

   The response contains the token string.
2. Install the client and register on a new Linux host:

   IP forwarding is not required to reach the node by its Mesh IP. If the node will advertise [CIDR routes](https://developers.cloudflare.com/mesh/features/routes/), enable persistent forwarding before connecting it:

   ```sh
   printf 'net.ipv4.ip_forward = 1\nnet.ipv6.conf.all.forwarding = 1\nnet.ipv6.conf.all.accept_ra = 2\n' | sudo tee /etc/sysctl.d/99-zzz-cloudflare-warp-connector.conf &&
   sudo sysctl --system
   ```

   ```sh
   curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg &&
   echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(. /etc/os-release && echo $VERSION_CODENAME) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list &&
   sudo apt-get update -qq && sudo apt-get install -y -qq cloudflare-warp
   ```

   ```sh
   sudo warp-cli --accept-tos connector new <TOKEN> && sudo warp-cli --accept-tos connect
   ```

   On RHEL 9 and later, enable the Extra Packages for Enterprise Linux (EPEL) repository before installing `cloudflare-warp`. EPEL provides dependencies required by the Cloudflare One Client UI. Turn on CodeReady Builder, then install the EPEL release package for your RHEL version:

   ```sh
   sudo subscription-manager repos --enable codeready-builder-for-rhel-$(rpm -E %rhel)-$(arch)-rpms &&
   sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E %rhel).noarch.rpm
   ```

   On Rocky Linux, AlmaLinux, and other RHEL-compatible distributions, run `sudo dnf config-manager --set-enabled crb && sudo dnf install -y epel-release` instead. For details, refer to [Run Mesh on Linux](https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/#rhel).

   Then install the package:

   ```sh
   curl -fsSL https://pkg.cloudflareclient.com/cloudflare-warp-ascii.repo | sudo tee /etc/yum.repos.d/cloudflare-warp.repo &&
   sudo dnf install -y cloudflare-warp
   ```

   ```sh
   sudo warp-cli --accept-tos connector new <TOKEN> && sudo warp-cli --accept-tos connect
   ```

The new replica will be in standby mode until the active replica disconnects.

## View replicas

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select an HA-enabled node. HA nodes display an **HA** badge in the overview table.
3. The node detail page shows a tab for each replica. Each tab displays:
   - **Active** or **Passive** badge
   - Mesh IP (IPv4 and IPv6)
   - Edge data center
   - Origin IP
   - Platform, version, and device name
   - Connected since timestamp

To view all replicas and their HA status, query the connections API endpoint:

```sh
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/warp_connector/{node_id}/connections" \
  -H "Authorization: Bearer {api_token}"
```

The response includes each replica with its `ha_status` (`active` or `passive`), connection details, and the Cloudflare data center it is connected to:

```json
{
	"success": true,
	"result": [
		{
			"id": "bf69f118-238e-11f1-b113-ee02f3be4a5b",
			"conns": [
				{
					"colo_name": "lhr16",
					"origin_ip": "34.105.147.200",
					"opened_at": "2026-03-19T12:25:47.400Z"
				}
			],
			"run_at": "2026-03-19T12:25:47.400Z",
			"ha_status": "active"
		},
		{
			"id": "e07272a6-21fc-11f1-8997-e28f01ba3991",
			"conns": [
				{
					"colo_name": "lhr14",
					"origin_ip": "35.246.81.139",
					"opened_at": "2026-03-19T02:38:37.203Z"
				}
			],
			"run_at": "2026-03-19T02:38:37.203Z",
			"ha_status": "passive"
		}
	]
}
```

## Manual failover

In addition to automatic failover when the active replica disconnects, you can manually promote a passive replica to active.

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select an HA-enabled node.
3. Select the tab for the passive replica you want to promote.
4. Select **Promote to active**.
5. In the confirmation dialog, select **Promote to active** to confirm.

Traffic reroutes to the promoted replica immediately. The previous active replica switches to passive standby.

To manually trigger failover, send a `PUT` request with the `client_id` of the replica you want to promote:

```sh
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/{account_id}/warp_connector/{node_id}/failover" \
  -H "Authorization: Bearer {api_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "e07272a6-21fc-11f1-8997-e28f01ba3991"
  }'
```

Get the `client_id` from the [connections endpoint](#view-replicas). Use the `id` field of the replica you want to promote.

## Considerations

### Setup requirements

- High availability is set at node creation time and cannot be changed afterward.
- You must install the client on at least two hosts for failover to work. A single replica means no redundancy.
- High availability requires that the Mesh node's [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) is configured to use [MASQUE](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#device-tunnel-protocol), the default protocol for the Cloudflare One Client. It does not work if the device profile uses WireGuard instead.

### Network configuration

- All replicas must be on the same subnet and have the same network routing configuration (Split Tunnels, static routes).
- HA provides resilience for CIDR route prefixes. Nodes without routes do not benefit from HA failover.

### Failover behavior

- Failover time depends on how quickly Cloudflare detects the active replica has disconnected (typically seconds).
- Inbound traffic (from Mesh clients to the subnet) fails over automatically on Cloudflare's network. Cloudflare routes traffic to the newly promoted active replica.
- Outbound traffic (from devices on the subnet through the Mesh node) does not fail over automatically. Your environment must detect that a different replica has been promoted to active and update routing tables to send traffic through the now-active host. There is no client-side failover for on-ramp traffic at this time.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/features/high-availability/#page","headline":"High availability","description":"Configure active-passive replicas to provide high availability for routed Cloudflare Mesh networks.","url":"https://developers.cloudflare.com/mesh/features/high-availability/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/features/high-availability/og.png?v=78b4108b2a8cfc72","dateModified":"2026-09-16","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Configure CIDR and hostname routes to send private network traffic through Cloudflare Mesh nodes.
title: Routes
image: https://developers.cloudflare.com/mesh/features/routes/og.png?v=df9ded2b2922b1cc
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Routes

Last updated Sep 16, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/features/routes/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

By default, a Mesh node is reachable only by its own [Mesh IP](https://developers.cloudflare.com/mesh/concepts/#mesh-ips). To make other devices on the subnet behind the node reachable — servers, databases, printers, IoT devices that cannot run the [Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/) — add a route to the node. A Mesh node supports two types of routes:

- **CIDR routes** — forward traffic for an IP range — private (for example, `10.0.0.0/24`) or public — through the node.
- **Hostname routes** — attract traffic for a hostname to the node instead of an IP. This works for a **private** hostname (for example, `wiki.internal.local`), which is useful when the application has an unknown or ephemeral IP, as well as a **public** hostname (for example, `www.example.com`), which routes that hostname's traffic through the node and egresses via the node's public IP.

When you add a route, the Mesh node acts as a gateway: traffic destined for the advertised CIDR or hostname is forwarded to the node, which delivers it to the appropriate host on the local network (or egresses it to the public Internet).

Both IPv4 and IPv6 CIDR routes are supported. IPv6 routes require that the Mesh node's [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) is configured to use [MASQUE](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#device-tunnel-protocol); they will not work if the device profile uses WireGuard instead.

## When to use routes

- **Without routes** — Devices on your Mesh can only reach the node itself by its Mesh IP. Services running directly on the node are reachable this way.
- **With routes** — Devices on your Mesh can reach any host on the subnet behind the node. Use this when you have infrastructure that cannot run the [Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/).

```
flowchart LR
  subgraph subnet["Subnet 10.0.0.0/24"]
    node["Mesh node <br> 10.0.0.1"]
    db["Database <br> 10.0.0.50"]
    printer["Printer <br> 10.0.0.100"]
  end
  client["Client device <br> 100.96.0.10"] --> CF((Cloudflare)) --> node
  node --> db
  node --> printer

```

## Manage CIDR routes

Use CIDR routes to forward traffic from your mesh node to devices on your local network.

### Add a route

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select your Mesh node.
3. Go to the **Routes** tab.
4. Select **Add route**.
5. Enter the private CIDR you want to route through this node (for example, `10.0.0.0/24`).
6. (Optionally) add a description for the route.
7. (Optionally) in **Virtual network**, select the [virtual network](https://developers.cloudflare.com/cloudflare-one/networks/virtual-networks/) for the route. The default virtual network is preselected.
8. Select **Add route**.

<details>

<summary>

Required API token permissions

</summary>

At least one of the following <a href="https://developers.cloudflare.com/fundamentals/api/reference/permissions/">token permissions</a> is required:

- <code>Cloudflare One Networks Write</code>
- <code>Cloudflare Tunnel Write</code>

</details>

*Create a tunnel routebash*

```bash
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/teamnet/routes" \
	--request POST \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"network": "10.0.0.0/24",
		"tunnel_id": "{mesh_node_id}",
		"comment": "Staging subnet",
		"virtual_network_id": "{virtual_network_id}"
	}'
```

`virtual_network_id` is optional. If you omit it, the route uses your default virtual network.

Within a virtual network, a CIDR can be assigned to only one Mesh node or [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/). To route overlapping IP ranges at different sites, assign each site's route to a different virtual network. Client devices reach a route only while they are connected to the route's virtual network.

### Edit a route

1. Go to **Networking** > **Mesh** > select your node > **Routes** tab.
2. Select the edit icon next to the route you want to modify.
3. Update the CIDR, description, or virtual network.
4. Select **Save**.

<details>

<summary>

Required API token permissions

</summary>

At least one of the following <a href="https://developers.cloudflare.com/fundamentals/api/reference/permissions/">token permissions</a> is required:

- <code>Cloudflare One Networks Write</code>
- <code>Cloudflare Tunnel Write</code>

</details>

*Update a tunnel routebash*

```bash
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/teamnet/routes/$ROUTE_ID" \
	--request PATCH \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"network": "10.0.0.0/24",
		"comment": "Updated description",
		"virtual_network_id": "{virtual_network_id}"
	}'
```

Omit `virtual_network_id` to keep the route's current virtual network.

### Delete a route

1. Go to **Networking** > **Mesh** > select your node > **Routes** tab.
2. Select the delete icon next to the route.
3. Confirm deletion.

<details>

<summary>

Required API token permissions

</summary>

At least one of the following <a href="https://developers.cloudflare.com/fundamentals/api/reference/permissions/">token permissions</a> is required:

- <code>Cloudflare One Networks Write</code>
- <code>Cloudflare Tunnel Write</code>

</details>

*Delete a tunnel routebash*

```bash
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/teamnet/routes/$ROUTE_ID" \
	--request DELETE \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

## Configure Split Tunnels

For traffic to reach your advertised CIDR, the range must route through Cloudflare on both the Mesh node and client devices.

### On the Mesh node

In your Mesh node's device profile, ensure the advertised CIDR routes through Cloudflare:

- **Include mode** (recommended for Mesh nodes): Add the CIDR to your include list.
- **Exclude mode**: Remove the CIDR (or its parent range) from your exclude list.

For example, if you are advertising `10.0.0.0/24` and your Split Tunnels exclude list contains `10.0.0.0/8`, you need to remove `10.0.0.0/8` and re-add the portions of the `10.0.0.0/8` range that you do not want to route through Cloudflare.

### On client devices

Repeat the same Split Tunnel configuration on the device profiles used by your client devices, ensuring the advertised CIDR routes through Cloudflare.

## Return traffic routing

The Mesh node forwards inbound traffic from Cloudflare to devices on the subnet. However, for **return traffic** (responses from subnet devices back to Mesh clients), the subnet devices need a route back to the Mesh node.

```
flowchart LR
  client["Client device <br> 100.96.0.10"] -- request --> CF((Cloudflare)) -- request --> node["Mesh node <br> 10.0.0.1"]
  node --> db["Database <br> 10.0.0.50"]
  db -. "response: <br> needs route to node" .-> node -. response .-> CF -. response .-> client

```

How you configure this depends on where the Mesh node is installed:

### Option 1: Mesh node is the default gateway

If the Mesh node is the subnet's default gateway (or is installed on the router), no additional configuration is needed. All traffic from subnet devices naturally routes through the node.

### Option 2: Mesh node is not the default gateway

If the Mesh node is a regular host on the subnet, configure the subnet's router to send Mesh traffic through the node. Add a static route:

- **Destination**: `100.96.0.0/12` (Mesh IP range)
- **Next hop**: The Mesh node's local subnet IP (for example, `10.0.0.1`)

This ensures that responses to Mesh clients are forwarded to the Mesh node for delivery through Cloudflare.

## Site-to-site routing

Mesh nodes can route traffic between private subnets at different sites. Each node advertises its local CIDR and routes the remote CIDR through Cloudflare.

To configure both sites, their routers, return routes, and verification tests, refer to [Connect two private networks with Cloudflare Mesh](https://developers.cloudflare.com/mesh/guides/connect-sites/).

## DNS filtering

To filter DNS queries from the subnet using [Cloudflare Gateway](https://developers.cloudflare.com/cloudflare-one/traffic-controls/dns-policies/):

1. **Configure DNS on your router**: Point your router's DNS to the Gateway resolver IPs:
   - `172.64.36.1`
   - `172.64.36.2`
2. **Add IP routes to your router**: On your router, add static routes pointing the Gateway resolver IPs to your Mesh node's local IP. This allows DNS traffic to reach Cloudflare through the node.
   - **Destination**: `172.64.36.1` → **Next hop**: `10.0.0.1` (local Mesh node)
   - **Destination**: `172.64.36.2` → **Next hop**: `10.0.0.1`
3. **Configure Split Tunnels**: Ensure the following IPs route through the Mesh node in your [Split Tunnels](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/split-tunnels/) configuration:
   - The subnet's internal DNS resolver IP
   - Gateway initial resolved IP range: `172.64.128.0/20` (IPv4) and `2606:4700:0cf1:4000::/64` (IPv6)

Gateway logs DNS queries with the private source IP of the originating device. You can use this to create [resolver policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/resolver-policies/) for internal DNS records.

## Hostname routes

Instead of advertising an IP range, you can attract traffic for a specific hostname to a Mesh node. When a user requests the hostname, Cloudflare Gateway assigns an initial resolved IP and routes the traffic through the node.

- **Private hostname** (for example, `wiki.internal.local`) — the node delivers the traffic to the application's private IP on the local network. Useful when the application has an unknown or ephemeral IP.
- **Public hostname** (for example, `www.example.com`) — the node egresses the traffic to the public Internet using its own public IP. This lets you use a Mesh node as a dedicated egress for that hostname.

Hostname routes replace [virtual networks](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/private-net/cloudflared/tunnel-virtual-networks/) as the way to reach resources: because a hostname is globally unique, **overlapping hostnames are not supported** and a hostname can only be routed to one node or tunnel at a time.

1. [Client device](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/)

   Requests `wiki.internal.local`
2. DNS query↓
3. [Cloudflare Gateway](https://developers.cloudflare.com/cloudflare-one/traffic-controls/)

   Returns a token IP, then rewrites the destination to the real private IP. `172.64.128.0/20`
4. [Hostname route](https://developers.cloudflare.com/mesh/features/routes/#hostname-routes)↓
5. [Mesh node](https://developers.cloudflare.com/mesh/)

   Forwards traffic to the host on the local network
6. ↓
7. Private host

   `wiki.internal.local` · `10.0.0.50`

For a deeper look at the packet flow behind hostname routing, refer to the [announcement blog post ↗︎](https://blog.cloudflare.com/tunnel-hostname-routing/).

### Prerequisites

- **Run a supported Mesh node version.** Hostname routing requires the Mesh node to run Linux Cloudflare One Client version `2026.6.822.0` or newer.
- **Configure the Mesh node's [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) to use [MASQUE](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#device-tunnel-protocol).** Hostname routing does not work if the device profile uses WireGuard instead.
- **Enable the Gateway proxy** with TCP, UDP, and ICMP:
  1. Go to **Traffic policies** > **Traffic settings**.
  2. In **Proxy and inspection**, turn on **Allow Secure Web Gateway to proxy traffic**.
  3. Select **TCP**.
  4. Select **UDP** (required to proxy traffic to internal DNS resolvers).
  5. (Recommended) To proxy traffic for diagnostic tools such as `ping` and `traceroute`, select **ICMP**. You may also need to [update your system](https://developers.cloudflare.com/cloudflare-one/traffic-controls/proxy/#icmp) to allow ICMP traffic through `cloudflared`.
  1. Add the following permission to your [`cloudflare_api_token` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/api_token):
     - `Zero Trust Write`
  2. Turn on the TCP and/or UDP proxy using the [`cloudflare_zero_trust_device_settings` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_device_settings) resource:

     ```tf
     resource "cloudflare_zero_trust_device_settings "global_warp_settings" {
     	account_id            = var.cloudflare_account_id
       gateway_proxy_enabled = true
     	gateway_udp_proxy_enabled = true
     }
     ```

     Cloudflare will now proxy traffic from enrolled devices, except for the traffic excluded in your [split tunnel settings](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/private-net/cloudflared/#3-route-private-network-ips-through-the-cloudflare-one-client). For more information on how Gateway forwards traffic, refer to [Gateway proxy](https://developers.cloudflare.com/cloudflare-one/traffic-controls/proxy/).
- **Route the following IPv4 ranges through Cloudflare** in the [Split Tunnel](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/split-tunnels/) configuration of **both** the Mesh node's device profile **and** your client device profiles. In Include mode, add each range. In Exclude mode, ensure none of them (or their parent ranges) are excluded.

  | Purpose | IPv4 |
  | --- | --- |
  | Mesh device IP range | `100.96.0.0/12` |
  | Cloudflare source IP range | `100.64.0.0/12` |

  The hostname routing (token IP) range ( `172.64.128.0/20`) and all Cloudflare One IPv6 ranges are [automatically routed through Cloudflare](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/split-tunnels/#automatically-managed-ranges) and do not need to be added manually.
- **Remove the hostname's top-level domain from [Local Domain Fallback](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/local-domains/)** on client devices, so the DNS query is sent to Cloudflare Gateway for resolution.

### Add a hostname route

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select your Mesh node.
3. Go to the **Routes** tab.
4. Select **Add route**, then select **Private hostname**.
5. Enter the fully qualified domain name (FQDN) you want to route through this node (for example, `wiki.internal.local`).<details><summary>

   Hostname format restrictions</summary>

   - **Character limit:** Must be less than 255 characters.
   - **Supported wildcards:** A single wildcard (<code>*</code>) is allowed, and it must represent a full DNS label. Example: <code>*.internal.local</code>
   - **Unsupported wildcards:** The following wildcard formats are not supported:
     - Partial wildcards such as <code>*-dev.internal.local</code> or <code>dev-*.internal.local</code>.
     - Wildcards in the middle, such as <code>foo*bar.internal.local</code> or <code>foo.*.internal.local</code>.
     - Multiple wildcards in the hostname, such as <code>*.*.internal.local</code>.
   - **Wildcard trimming**: Leading wildcards (<code>*</code>) are trimmed off and an implicit dot (<code>.</code>) is assumed. For example, <code>*.internal.local</code> is saved as <code>internal.local</code> but will match all subdomains at the wildcard level (covers <code>foo.internal.local</code> but not <code>foo.bar.internal.local</code>).
   - **Dot trimming:** Leading and ending dots (<code>.</code>) are allowed but trimmed off.</details>

6. (Optionally) add a description for the route.
7. Select **Add hostname**.

<details>

<summary>

Required API token permissions

</summary>

At least one of the following <a href="https://developers.cloudflare.com/fundamentals/api/reference/permissions/">token permissions</a> is required:

- <code>Cloudflare One Networks Write</code>
- <code>Cloudflare Tunnel Write</code>

</details>

*Create hostname routebash*

```bash
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/zerotrust/routes/hostname" \
	--request POST \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"hostname": "wiki.internal.local",
		"tunnel_id": "{mesh_node_id}",
		"comment": "Internal wiki"
	}'
```

### Configure DNS resolution

For a **private** hostname, Gateway must be able to resolve the hostname to its private IP. How you configure this depends on whether DNS resolution and application traffic use the **same** connector or **different** connectors.

#### The node resolves the hostname (default)

By default, the Mesh node resolves the hostname using the DNS resolver configured on its host machine (for example, in `/etc/resolv.conf` on Linux) — the same way `cloudflared` does. If the node can already resolve the hostname to its private IP through that resolver, no further configuration is required.

If the node cannot resolve the hostname on its own, the simplest option is to add an entry to the node's hosts file (for example, `/etc/hosts` on Linux) mapping the hostname to its private IP. Unlike a Cloudflare Tunnel, a Mesh node does **not** require you to run a dedicated DNS server:

*/etc/hoststxt*

```txt
10.0.0.50 wiki.internal.local
```

#### Split DNS: DNS and application traffic use different connectors

You only need a Gateway [resolver policy](https://developers.cloudflare.com/cloudflare-one/traffic-controls/resolver-policies/) when the DNS query must be sent to a **different** connector than the application traffic — for example, the internal DNS server sits behind one Mesh node or Cloudflare Tunnel, while the application is reached through another. In that case:

1. Add a [CIDR route](#add-a-route) for the DNS server's IP so Gateway can reach it through the connector where the DNS server lives (a Mesh node or a [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/)).
2. Create a [resolver policy](https://developers.cloudflare.com/cloudflare-one/traffic-controls/resolver-policies/) that sends DNS queries for the hostname (or its domain) to that internal DNS server.

Where to run the DNS server

If the DNS server is reached through a Mesh node, you cannot run it on the **same machine** as that node — the node's DNS interface binds port `53`. Host the DNS server on a separate machine in the same private network. In that case, configure return routes on the subnet so the DNS server's responses can reach the client:

- **Mesh device IP range**: `100.96.0.0/12` → next hop is the Mesh node's local IP
- **Initial resolved IP range**: `172.64.128.0/20` → next hop is the Mesh node's local IP

For a **public** hostname, the Mesh node handles resolution: Gateway sends the DNS query to the node, the node resolves it through its upstream DNS provider, and then routes the packet to the destination and egresses using its own public IP. No internal DNS server or resolver policy is required.

### Secure hostname traffic

After adding a hostname route, secure it with either an [Access self-hosted application](https://developers.cloudflare.com/cloudflare-one/access-controls/applications/non-http/self-hosted-private-app/) or [Gateway network policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/). For details and examples, refer to [Connect a private hostname](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/private-net/cloudflared/connect-private-hostname/#3-recommended-filter-network-traffic-with-gateway).

### Limitations

Starting with [Chrome 142 ↗︎](https://developer.chrome.com/release-notes/142), Local Network Access (LNA) restricts requests from websites to local IP addresses. LNA is implemented at the Chromium engine level, so this affects all Chromium-based browsers (for example, Microsoft Edge, Brave, and Opera), not only Google Chrome. This can affect accounts whose Gateway initial resolved IP range is still drawn from Carrier-Grade NAT (CGNAT) address space (`100.64.0.0/10`) — for example, the legacy default range `100.80.0.0/16`, or a custom range configured within CGNAT space. These browsers categorize such addresses as belonging to a local network. When a website loaded from a public IP makes subrequests to a domain resolved through an initial resolved IP in this space, the browser treats this as a public-to-local network request and displays a prompt asking the user to allow access to devices on the local network. The browser blocks requests to these domains until the user accepts this prompt.

This commonly occurs when an Egress policy matches broadly used domains (such as `cloudfront.net` or `github.com`), causing subrequests from public pages to resolve into CGNAT space.

Accounts using the current default initial resolved IP range (`172.64.128.0/20`) are not affected, because this range is public Cloudflare address space rather than CGNAT. If your account was created before this default changed, or if you configured a custom CGNAT-space range, refer to [Configure initial resolved IPs](https://developers.cloudflare.com/cloudflare-one/networks/routes/configure-initial-resolved-ips/) to move to a non-CGNAT range instead of relying on the following browser workarounds.

The workarounds below use Google Chrome Enterprise policies. If your organization manages a different Chromium-based browser, consult that browser's enterprise policy documentation for an equivalent control.

#### Iframes

If the affected request originates from within an iframe (for example, an application embedded in a third-party portal), the iframe must declare the `local-network-access` permission for the browser prompt to appear in the parent frame:

- **Chrome 142-144**: Use the `allow="local-network-access"` attribute on the iframe element.
- **Chrome 145+**: The permission was split into `allow="local-network"` and `allow="loopback-network"`.

If iframes are nested, every iframe in the chain must include the appropriate attribute. Since third-party applications control their own iframe attributes, this may not be configurable by the end user.

#### Workarounds

To avoid this issue, choose one of the following options:

- **Override IP address space classification (Chrome 146+)**: Use the [`LocalNetworkAccessIpAddressSpaceOverrides` ↗︎](https://chromeenterprise.google/policies/#LocalNetworkAccessIpAddressSpaceOverrides) Chrome Enterprise policy to reclassify your CGNAT-space initial resolved IP range (for example, `100.80.0.0/16`) as public. This is the most targeted fix because it only changes the classification for the initial resolved IP range rather than disabling security checks entirely.
- **Allow specific URLs (Chrome 140+)**: Use the [`LocalNetworkAccessAllowedForUrls` ↗︎](https://chromeenterprise.google/policies/#LocalNetworkAccessAllowedForUrls) Chrome Enterprise policy to exempt specific websites from Local Network Access checks. Note that `https://*` is a valid entry to disable checks for all URLs.
- **Allow specific URLs (Chrome 146+)**: Use the [`LocalNetworkAllowedForUrls` ↗︎](https://chromeenterprise.google/policies/#LocalNetworkAllowedForUrls) Chrome Enterprise policy, which replaces `LocalNetworkAccessAllowedForUrls` starting in Chrome 146.
- **Opt out of Local Network Access restrictions (Chrome 142-152)**: Use the [`LocalNetworkAccessRestrictionsTemporaryOptOut` ↗︎](https://chromeenterprise.google/policies/#LocalNetworkAccessRestrictionsTemporaryOptOut) Chrome Enterprise policy to completely opt out of Local Network Access restrictions. This is a temporary policy and will be removed after Chrome 152.
- **Disable the Chrome feature flag**: Go to `chrome://flags` and set the **Local Network Access Checks** flag to *Disabled*. This approach is suitable for individual users but not for enterprise-wide deployment.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/features/routes/#page","headline":"Routes","description":"Configure CIDR and hostname routes to send private network traffic through Cloudflare Mesh nodes.","url":"https://developers.cloudflare.com/mesh/features/routes/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/features/routes/og.png?v=df9ded2b2922b1cc","dateModified":"2026-09-16","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Connect devices, servers, or private networks with Cloudflare Mesh, or deploy nodes on Linux hosts and in containers.
title: Guides
image: https://developers.cloudflare.com/mesh/guides/og.png?v=f47253a4437bcc4a
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Guides

Last updated Oct 29, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/guides/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

- [Connect two devices privately with Cloudflare Mesh](https://developers.cloudflare.com/mesh/guides/connect-client-devices/)
- [Connect two servers with Cloudflare Mesh](https://developers.cloudflare.com/mesh/guides/connect-servers/)
- [Connect two private networks with Cloudflare Mesh](https://developers.cloudflare.com/mesh/guides/connect-sites/)
- [Run Mesh on Linux](https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/)
- [Run Mesh in Docker / Kubernetes](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/)

For connection failures, refer to [Troubleshoot Cloudflare Mesh connectivity](https://developers.cloudflare.com/mesh/troubleshooting/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/mesh/guides/#page","headline":"Guides","description":"Connect devices, servers, or private networks with Cloudflare Mesh, or deploy nodes on Linux hosts and in containers.","url":"https://developers.cloudflare.com/mesh/guides/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/guides/og.png?v=f47253a4437bcc4a","dateModified":"2026-10-29","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Connect two laptops, phones, or desktops privately with Cloudflare Mesh and verify connectivity between them.
title: Connect two devices privately with Cloudflare Mesh
image: https://developers.cloudflare.com/mesh/guides/connect-client-devices/og.png?v=835297b7377c1ee0
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Connect two devices privately with Cloudflare Mesh

Last updated Oct 29, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/guides/connect-client-devices/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Connect two laptops, phones, or desktops by enrolling both devices in Cloudflare Mesh. Each device receives a private [Mesh IP](https://developers.cloudflare.com/mesh/concepts/#mesh-ips) and can reach the other device without a Mesh node.

## Prerequisites

Use two devices supported by the [Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/download/). One device must run a service that the other device can test, such as SSH or HTTP.

Before you enroll the devices, configure the [required account settings](https://developers.cloudflare.com/mesh/get-started/#required-account-settings). You do not need to create a Mesh node for device-to-device connectivity.

## 1. Connect the first device

Use the Mesh dashboard to find the installer and organization name:

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select **Add participant** > **Add device**.
3. Select Windows, macOS, Linux, iOS, or Android.
4. Use the provided link or QR code to install the Cloudflare One Client.
5. Open the client and select **Cloudflare Zero Trust** when prompted for a connection type.
6. Enter the organization name shown in the dashboard and complete authentication.

The workflow provides installation information. It does not enroll the device automatically. For manual enrollment instructions, refer to [Enroll a device](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/manual-deployment/).

### Headless Windows, macOS, and Linux devices

Do not use interactive CLI enrollment on a device without a browser. Instead, [create a Service Auth enrollment policy](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/device-enrollment/#check-for-service-token). Configure the [`organization`](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/mdm-deployment/parameters/#organization), [`auth_client_id`](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/mdm-deployment/parameters/#auth_client_id), and [`auth_client_secret`](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/mdm-deployment/parameters/#auth_client_secret) managed deployment parameters.

For platform-specific installation methods and configuration file locations, refer to [Managed deployment](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/mdm-deployment/). For a complete Linux example, refer to [Deploy the Cloudflare One Client on headless Linux machines](https://developers.cloudflare.com/cloudflare-one/tutorials/deploy-client-headless-linux/).

This method works on [supported Windows, macOS, and Linux systems](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/download/). Service-token devices use the shared identity `non_identity@<team-name>.cloudflareaccess.com`. Policies based on identity provider users or groups do not apply to these devices. To assign device profiles, use the expression `identity.service_token_uuid == "<SERVICE_TOKEN_ID>"`, where `<SERVICE_TOKEN_ID>` is the service token resource UUID (`id`), not its `auth_client_id`. Place this [Service Token selector](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/#service-token) before broader OS or email profiles. Use the shared non-identity email only when all Service Auth devices should match the profile.

After enrollment, the device receives a Mesh IP. The device appears in the participant table under **Networking** > **Mesh**.

## 2. Connect the second device

Repeat the enrollment procedure on the second device. Use the same Cloudflare account and Zero Trust organization.

Confirm that both devices appear as **Online** under **Networking** > **Mesh**. Record the Mesh IP of the device that runs the service.

## 3. Route Mesh traffic through Cloudflare

Check the [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) applied to each device. The profile must use Traffic and DNS mode and route your Mesh IP range through Cloudflare.

- In Split Tunnels **Include mode**, include `100.96.0.0/12`.
- In Split Tunnels **Exclude mode**, make sure neither `100.96.0.0/12` nor a parent range such as `100.64.0.0/10` is excluded.

Use your custom device IP range instead of `100.96.0.0/12` if you changed the default. For configuration instructions, refer to [Split Tunnels](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/split-tunnels/).

## 4. Allow inbound traffic

Configure the destination device firewall to accept the service traffic. Windows Firewall blocks inbound traffic from `100.96.0.0/12` by default. Add a rule that allows the required protocols and ports from the Mesh IP range.

On macOS and Linux, verify that custom firewall rules permit the same traffic. You do not need to open the service to the public Internet.

## Verify connectivity

Test the application protocol that you intend to use. For example, test a service that listens on TCP port `22`:

```sh
nc -vz <DESTINATION-IP> 22
```

```powershell
Test-NetConnection <DESTINATION-IP> -Port 22
```

For an HTTP service, open `http://<DESTINATION-IP>:<PORT>` in a browser.

Replace `<DESTINATION-IP>` with the destination Mesh IP or private IP. Replace port `22` or `<PORT>` with the port used by your service.

If you turned on the ICMP Gateway proxy, you can also run `ping <DESTINATION-IP>` as a diagnostic check. A connected participant status does not confirm that the application protocol can reach the destination.

Use the destination device Mesh IP for `<DESTINATION-IP>`.

## Secure and monitor the connection

Use [Gateway network policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/) to control which sources can reach each destination IP and port. You can combine network policies with [device posture checks](https://developers.cloudflare.com/cloudflare-one/reusable-components/posture-checks/) for enrolled client devices.

Review allowed and blocked connections in [Gateway network logs](https://developers.cloudflare.com/cloudflare-one/insights/logs/dashboard-logs/gateway-logs/#network). Client device traffic includes the enrolled user identity. Mesh node traffic uses the identity `warp_connector@<your-team-name>.cloudflareaccess.com`.

If a participant is online but the service is unreachable, refer to [Troubleshoot Cloudflare Mesh connectivity](https://developers.cloudflare.com/mesh/troubleshooting/).

## Next steps

- [Connect two servers](https://developers.cloudflare.com/mesh/guides/connect-servers/) by their Mesh IPs.
- [Connect two private networks](https://developers.cloudflare.com/mesh/guides/connect-sites/) through routed subnets.
- [Configure routes](https://developers.cloudflare.com/mesh/features/routes/) for devices that cannot run the client.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/guides/connect-client-devices/#page","headline":"Connect two devices privately with Cloudflare Mesh","description":"Connect two laptops, phones, or desktops privately with Cloudflare Mesh and verify connectivity between them.","url":"https://developers.cloudflare.com/mesh/guides/connect-client-devices/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/guides/connect-client-devices/og.png?v=835297b7377c1ee0","dateModified":"2026-10-29","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Connect two Linux servers with Cloudflare Mesh and reach services by private Mesh IP without exposing them to the public Internet.
title: Connect two servers with Cloudflare Mesh
image: https://developers.cloudflare.com/mesh/guides/connect-servers/og.png?v=d8b47ca1763a947b
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Connect two servers with Cloudflare Mesh

Last updated Oct 29, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/guides/connect-servers/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Install one Cloudflare Mesh node on each Linux server. Each server receives a private Mesh IP, so it can reach services on the other server through Cloudflare. Neither server needs a public IP address or a service exposed to the public Internet.

This setup reaches services running **on the nodes themselves**. To connect hosts behind the nodes instead, follow [Connect two sites](https://developers.cloudflare.com/mesh/guides/connect-sites/).

## Prerequisites

- Two servers running a [supported Linux distribution](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/download/#linux), with administrator access
- A service listening on each server if you want to test both directions, such as SSH on TCP port `22`
- Netcat ( `nc`) installed on the servers where you will run the TCP tests
- Outbound access from both servers to the [Cloudflare One Client IPs and ports](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/firewall/)

Before you begin, [set up Cloudflare Mesh](https://developers.cloudflare.com/mesh/get-started/) for your account. The setup wizard configures device enrollment, Mesh IP assignment, enrolled-device reachability, and Gateway proxying.

If your account already uses Cloudflare One, verify the [required account settings](https://developers.cloudflare.com/mesh/get-started/#required-account-settings). Existing settings are not overwritten by the setup wizard.

To run a node in a container, refer to [Run Mesh in Docker or Kubernetes](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/).

## Connect the first server

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select **Add participant** > **Add node**.
3. Name the node `server-a`, then select **Create node**.
4. Select **Linux** and run the displayed installation and registration commands on the first server. Keep the node token private.
5. Confirm that `server-a` appears as **Online** in the Mesh dashboard. Record its **Mesh IP**.

## Connect the second server

1. In **Networking** > **Mesh**, select **Add participant** > **Add node**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Name the new node `server-b`, select **Create node**, then select **Linux**.
3. Run the new installation and registration commands on the second server. Do not reuse the first node token: each server needs its own node identity.
4. Confirm that `server-b` appears as **Online** and record its **Mesh IP**.

When a service runs on the node itself, you do not need a CIDR route, router changes, or IP forwarding. [IP forwarding](https://developers.cloudflare.com/mesh/best-practices/#make-ip-forwarding-persistent/) is only needed when a node routes traffic for other hosts.

## Allow service traffic

On each destination server, confirm the service listens on the Mesh IP or on all interfaces. A service bound only to a separate local-network IP cannot accept connections to its Mesh IP. Allow the required port from the other server's Mesh IP in the host firewall, and check any cloud firewall or security group. Scope these rules to Mesh IPs instead of opening the port to the public Internet.

Confirm that the [Gateway proxy](https://developers.cloudflare.com/cloudflare-one/traffic-controls/proxy/) handles the service protocol and that any [Gateway network policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/) permit the connection.

## Verify connectivity

If both servers run SSH, test each direction using the other server's Mesh IP:

1. On `server-a`, test TCP port `22` on `server-b`:

   ```sh
   nc -vz <SERVER-B-MESH-IP> 22
   ```

2. On `server-b`, test TCP port `22` on `server-a`:

   ```sh
   nc -vz <SERVER-A-MESH-IP> 22
   ```

Replace the Mesh IP placeholders with the addresses shown in the dashboard. If you use another service, substitute its port. **Online** means the node is connected to Cloudflare. A successful service test confirms that traffic reaches the destination. `ping` is only useful when the ICMP Gateway proxy is turned on.

If a test fails, refer to [Troubleshoot Cloudflare Mesh connectivity](https://developers.cloudflare.com/mesh/troubleshooting/).

## Secure and monitor the connection

Use [Gateway network policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/) to control which sources can reach each destination IP and port. You can combine network policies with [device posture checks](https://developers.cloudflare.com/cloudflare-one/reusable-components/posture-checks/) for enrolled client devices.

Review allowed and blocked connections in [Gateway network logs](https://developers.cloudflare.com/cloudflare-one/insights/logs/dashboard-logs/gateway-logs/#network). Client device traffic includes the enrolled user identity. Mesh node traffic uses the identity `warp_connector@<your-team-name>.cloudflareaccess.com`.

## Next steps

- [Connect two private networks](https://developers.cloudflare.com/mesh/guides/connect-sites/) through routed subnets.
- [Connect two devices](https://developers.cloudflare.com/mesh/guides/connect-client-devices/) by Mesh IP.
- [Connect Workers to Mesh](https://developers.cloudflare.com/workers-vpc/examples/connect-to-cloudflare-mesh/) with a VPC Network binding.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/guides/connect-servers/#page","headline":"Connect two servers with Cloudflare Mesh","description":"Connect two Linux servers with Cloudflare Mesh and reach services by private Mesh IP without exposing them to the public Internet.","url":"https://developers.cloudflare.com/mesh/guides/connect-servers/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/guides/connect-servers/og.png?v=d8b47ca1763a947b","dateModified":"2026-10-29","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Connect two sites with Cloudflare Mesh by routing traffic in both directions between private subnets through Mesh nodes.
title: Connect two private networks with Cloudflare Mesh
image: https://developers.cloudflare.com/mesh/guides/connect-sites/og.png?v=092a184bc09e6b42
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Connect two private networks with Cloudflare Mesh

Last updated Oct 29, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/guides/connect-sites/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Connect two sites, offices, or cloud networks with [Cloudflare Mesh](https://developers.cloudflare.com/mesh/). A Linux Mesh node at each site carries traffic between the private subnets through Cloudflare. Hosts behind the nodes do not need the Cloudflare One Client.

This example uses separate subnets and tests traffic in both directions:

| Site | Private subnet | Mesh node local IP | Test host IP |
| --- | --- | --- | --- |
| Site A | `10.0.0.0/24` | `10.0.0.10` | `10.0.0.50` |
| Site B | `192.168.1.0/24` | `192.168.1.10` | `192.168.1.50` |

Replace these addresses with your own. The subnets must not overlap each other or your Mesh IP range.

## Prerequisites

- A [supported Linux host](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/download/#linux) at each site, with a stable local IP and administrator access
- Access to each site's router or cloud route table to direct traffic to its local Mesh node
- A test service on a host in each subnet, such as SSH on TCP port `22`
- Netcat ( `nc`) installed on the hosts where you will run the TCP tests

Before you begin, [set up Cloudflare Mesh](https://developers.cloudflare.com/mesh/get-started/) for your account. The setup wizard configures device enrollment, Mesh IP assignment, enrolled-device reachability, and Gateway proxying.

If your account already uses Cloudflare One, verify the [required account settings](https://developers.cloudflare.com/mesh/get-started/#required-account-settings). Existing settings are not overwritten by the setup wizard.

For containers, use separate node identities and review the [container source NAT behavior](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/#source-nat/) before configuring return routes.

## Connect a node at each site

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select **Add participant** > **Add node**. Name the node `site-a`, select **Create node**, and then select **Linux**.
3. Run the displayed installation and registration commands on the Linux host at Site A. Confirm that the node appears as **Online**.
4. Repeat the procedure at Site B with a new node named `site-b`. Use the new node's installation commands and token. Each site needs a distinct node identity.
5. Confirm both nodes appear as **Online** and record their local IPs and Mesh IPs.

Each node must forward traffic for its subnet. The Linux installation commands include persistent IP forwarding. On both hosts, verify that IPv4 forwarding is on:

```sh
sysctl net.ipv4.ip_forward
```

If the output is not `net.ipv4.ip_forward = 1`, follow [Make IP forwarding persistent](https://developers.cloudflare.com/mesh/best-practices/#make-ip-forwarding-persistent/). Cloud virtual machines may also require [provider-specific forwarding settings](https://developers.cloudflare.com/mesh/best-practices/#cloud-vpc-deployments/).

If a node uses UFW, firewalld, nftables, or another host firewall, allow forwarded traffic between its local network and Cloudflare One Client interfaces. Also check that cloud firewall rules or security groups allow the forwarded traffic. Enabling `net.ipv4.ip_forward` does not override firewall rules that drop forwarded packets.

## Advertise each local subnet

A [CIDR route](https://developers.cloudflare.com/mesh/features/routes/#manage-cidr-routes) tells Cloudflare which node can reach a private subnet.

1. In the Cloudflare dashboard, go to **Networking** > **Mesh** and select `site-a`. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. In the **Routes** tab, select **Add route**. Enter `10.0.0.0/24` and select **Add route**.
3. Select `site-b` and add a route for `192.168.1.0/24`.

Advertise only subnets that the node can reach on its own local network. A route to a node's Mesh IP is not a substitute for a route to hosts behind that node.

## Route remote subnets through Cloudflare

Each node must send traffic for the **other** site's subnet through Cloudflare. Check the [Split Tunnels](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/split-tunnels/) settings in the device profile applied to each node:

| Node | Include mode | Exclude mode |
| --- | --- | --- |
| `site-a` | Include `100.96.0.0/12` and `192.168.1.0/24` | Do not exclude either range or a parent range containing it |
| `site-b` | Include `100.96.0.0/12` and `10.0.0.0/24` | Do not exclude either range or a parent range containing it |

Use your configured device IP range if it differs from `100.96.0.0/12`. On each node, run `warp-cli settings` to confirm which [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/#via-the-cli) is applied. If both nodes share a profile, changing it affects both sites. Confirm that `site-a` can still reach `10.0.0.50` locally and `site-b` can still reach `192.168.1.50` locally.

## Configure the site routers

When a node is not the local default gateway, add static routes on the site's router. The next hop is the node's **local IP**, not its Mesh IP:

1. On the Site A router, route `192.168.1.0/24` to `10.0.0.10`.
2. On the Site B router, route `10.0.0.0/24` to `192.168.1.10`.

These routes also provide the return path: a reply from Site B to a Site A host returns through `site-b`, and vice versa. To reach hosts from enrolled devices by Mesh IP, also route `100.96.0.0/12` to the local node at **each** site. If a node is the site's default gateway, hosts already send traffic through it and those additional static routes are not needed.

## Verify both directions

Confirm that an SSH service listens on each test host, or use the port of another service. Test from a host **behind** each node, not only from the nodes themselves:

1. On Site A host `10.0.0.50`, test Site B host `192.168.1.50`:

   ```sh
   nc -vz 192.168.1.50 22
   ```

2. On Site B host `192.168.1.50`, test Site A host `10.0.0.50`:

   ```sh
   nc -vz 10.0.0.50 22
   ```

A successful TCP connection confirms the service path. If a test fails, check forwarding, Split Tunnels, return routes, destination firewalls, and [Gateway network policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/). `ping` requires the ICMP Gateway proxy. For a symptom-by-symptom checklist, refer to [Troubleshoot Cloudflare Mesh connectivity](https://developers.cloudflare.com/mesh/troubleshooting/).

## Secure and monitor the connection

Use [Gateway network policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/) to control which sources can reach each destination IP and port. You can combine network policies with [device posture checks](https://developers.cloudflare.com/cloudflare-one/reusable-components/posture-checks/) for enrolled client devices.

Review allowed and blocked connections in [Gateway network logs](https://developers.cloudflare.com/cloudflare-one/insights/logs/dashboard-logs/gateway-logs/#network). Client device traffic includes the enrolled user identity. Mesh node traffic uses the identity `warp_connector@<your-team-name>.cloudflareaccess.com`.

## Next steps

- [Connect two servers](https://developers.cloudflare.com/mesh/guides/connect-servers/) by Mesh IP without subnet routing.
- [Configure high availability](https://developers.cloudflare.com/mesh/features/high-availability/) for routed subnets.
- [Review MTU recommendations](https://developers.cloudflare.com/mesh/best-practices/#mtu-and-packet-fragmentation/) if large packets fail.
- [Explore other VPN replacement scenarios](https://developers.cloudflare.com/cloudflare-one/setup/replace-vpn/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/guides/connect-sites/#page","headline":"Connect two private networks with Cloudflare Mesh","description":"Connect two sites with Cloudflare Mesh by routing traffic in both directions between private subnets through Mesh nodes.","url":"https://developers.cloudflare.com/mesh/guides/connect-sites/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/guides/connect-sites/og.png?v=092a184bc09e6b42","dateModified":"2026-10-29","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Run a Cloudflare Mesh node as a Docker container for Docker Compose, Kubernetes, and CI/CD environments.
title: Run Mesh in Docker / Kubernetes
image: https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/og.png?v=164eeb2486ebbcab
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Run Mesh in Docker / Kubernetes

Last updated Oct 29, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

The [`cloudflare/mesh` ↗︎](https://hub.docker.com/r/cloudflare/mesh) Docker image packages a Cloudflare Mesh node for Linux containers. It runs the Cloudflare One Client's `warp-svc` daemon headlessly in a minimal [Wolfi ↗︎](https://wolfi.dev/)-based runtime.

Use the container image to add Mesh nodes to Docker Compose stacks, Kubernetes clusters, and CI/CD pipelines — without installing packages on the host.

## Supported architectures

The `latest` tag is a multi-platform manifest. Docker automatically selects the appropriate image for the host architecture.

| Architecture | Tag |
| --- | --- |
| Multi-arch | `latest` |
| x86-64 | `latest-amd64` |
| ARM64 | `latest-arm64` |

## Prerequisites

Before starting the container, create a Mesh node and obtain its token.

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select **Add participant** > **Add node**.
3. Enter a name for your node (for example, `k8s-gateway` or `docker-agent`).
4. Select **Create node**.
5. Select **Kubernetes**, **Docker Compose**, or **Docker CLI**.
6. Follow the displayed instructions. The dashboard masks the node token but includes it when required by a copied command. Docker Compose configurations and Kubernetes manifests reference a secret instead of containing the token.

With an API token that has either `Cloudflare One Connectors Write` or `Cloudflare One Connector: WARP Write` permission, create a node and retrieve its connector token:

```bash
set -euo pipefail

NODE_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/warp_connector" \
		--request POST \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
		--header "Content-Type: application/json" \
		--data '{"name":"k8s-gateway"}'
)

jq -e '.success == true and (.result.id | type == "string")' \
	<<< "$NODE_RESPONSE" > /dev/null
NODE_ID=$(jq -r '.result.id' <<< "$NODE_RESPONSE")

TOKEN_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/warp_connector/$NODE_ID/token" \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
)

MESH_NODE_TOKEN=$(jq -er \
	'select(.success == true) | .result | select(type == "string" and length > 0)' \
	<<< "$TOKEN_RESPONSE")
```

Install `jq`, then set `ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN` before running the commands. The commands stop on an HTTP or API error. Do not continue until they return zero and set `NODE_ID` and `MESH_NODE_TOKEN`. If token retrieval fails after node creation, retry only the token request with the existing `NODE_ID`. Do not rerun the node creation request. Pass `MESH_NODE_TOKEN` to the container.

Note

Mesh nodes can also be managed with Terraform using the [`cloudflare_zero_trust_tunnel_warp_connector` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_warp_connector) resource. To manage node configuration, use [`cloudflare_zero_trust_tunnel_warp_connector_config` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_warp_connector_config).

If this is your first Mesh node, configure the [required account settings](https://developers.cloudflare.com/mesh/get-started/#required-account-settings). You can use the dashboard wizard, APIs, or Terraform.

Caution

Do not commit Mesh node tokens to source control. Use environment variables, `.env` files excluded from version control, or a secrets manager.

## Deploy with Docker Compose

Docker Compose is the recommended way to run a Mesh node alongside your application services. Add a `cloudflare-mesh` service to your `compose.yaml`:

```yaml
services:
  cloudflare-mesh:
    image: cloudflare/mesh:latest
    container_name: cloudflare-mesh
    cap_add:
      - NET_ADMIN
      - NET_RAW
    devices:
      - /dev/net/tun:/dev/net/tun
    environment:
      MESH_NODE_TOKEN: ${MESH_NODE_TOKEN}
      SRCNAT_ENABLED: "true"
    sysctls:
      net.ipv4.ip_forward: "1"
      net.ipv6.conf.all.forwarding: "1"
      net.ipv6.conf.default.forwarding: "1"
    volumes:
      - mesh_data:/var/lib/cloudflare-warp
    restart: unless-stopped

volumes:
  mesh_data:
```

Start the stack:

```sh
MESH_NODE_TOKEN="<YOUR-TOKEN>" docker compose up -d
```

Verify the node is connected:

```sh
docker exec cloudflare-mesh warp-cli status
```

## Deploy with Docker CLI

For a standalone container without Compose:

```sh
docker run -d \
  --name cloudflare-mesh \
  --cap-add NET_ADMIN \
  --cap-add NET_RAW \
  --device /dev/net/tun \
  --sysctl net.ipv4.ip_forward=1 \
  --sysctl net.ipv6.conf.all.forwarding=1 \
  --sysctl net.ipv6.conf.default.forwarding=1 \
  -e MESH_NODE_TOKEN="$MESH_NODE_TOKEN" \
  -e SRCNAT_ENABLED=true \
  -v mesh_data:/var/lib/cloudflare-warp \
  --restart unless-stopped \
  cloudflare/mesh:latest
```

## Deploy on Kubernetes

This example creates a one-replica `StatefulSet` with persistent registration state. It requires a Kubernetes cluster that permits `NET_ADMIN`, `NET_RAW`, and `/dev/net/tun` host access (for example, GKE Standard).

### 1. Create the token Secret

```sh
kubectl create secret generic cloudflare-mesh \
  --from-literal=MESH_NODE_TOKEN="$MESH_NODE_TOKEN"
```

### 2. Apply the manifest

Save the following as `cloudflare-mesh.yaml`:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: cloudflare-mesh
spec:
  clusterIP: None
  selector:
    app: cloudflare-mesh
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cloudflare-mesh
spec:
  serviceName: cloudflare-mesh
  replicas: 1
  selector:
    matchLabels:
      app: cloudflare-mesh
  template:
    metadata:
      labels:
        app: cloudflare-mesh
    spec:
      containers:
        - name: mesh
          image: cloudflare/mesh:latest
          env:
            - name: MESH_NODE_TOKEN
              valueFrom:
                secretKeyRef:
                  name: cloudflare-mesh
                  key: MESH_NODE_TOKEN
            - name: SRCNAT_ENABLED
              value: "true"
          securityContext:
            capabilities:
              add:
                - NET_ADMIN
                - NET_RAW
          volumeMounts:
            - name: warp-data
              mountPath: /var/lib/cloudflare-warp
            - name: dev-net-tun
              mountPath: /dev/net/tun
      volumes:
        - name: dev-net-tun
          hostPath:
            path: /dev/net/tun
            type: CharDevice
  volumeClaimTemplates:
    - metadata:
        name: warp-data
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
```

### 3. Verify the node

```sh
kubectl apply -f cloudflare-mesh.yaml
kubectl rollout status statefulset/cloudflare-mesh
kubectl exec cloudflare-mesh-0 -- warp-cli status
```

The `PersistentVolumeClaim` preserves the Mesh registration across Pod restarts.

Note

GKE Autopilot is not supported because it blocks the required `/dev/net/tun` `hostPath`.

## Kubernetes sidecar

To connect an application container to Mesh, add the Mesh image as a sidecar in the same Pod. Containers in a Pod share the network namespace, so the Mesh sidecar connects the application to Cloudflare without any application changes.

### 1. Create the token Secret

Create a separate Mesh node and Kubernetes Secret for the sidecar:

```sh
kubectl create secret generic cloudflare-mesh-sidecar \
  --from-literal=MESH_NODE_TOKEN="$MESH_NODE_TOKEN"
```

### 2. Apply the manifest

Save the following as `cloudflare-mesh-sidecar.yaml`:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: cloudflare-mesh-sidecar-headless
spec:
  clusterIP: None
  selector:
    app: cloudflare-mesh-sidecar
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cloudflare-mesh-sidecar
spec:
  serviceName: cloudflare-mesh-sidecar-headless
  replicas: 1
  selector:
    matchLabels:
      app: cloudflare-mesh-sidecar
  template:
    metadata:
      labels:
        app: cloudflare-mesh-sidecar
    spec:
      containers:
        - name: application
          image: busybox:1.37.0
          command:
            - sh
            - -c
            - |
              echo "Hello from the Kubernetes sidecar example" > /tmp/index.html
              httpd -f -p 8080 -h /tmp
          ports:
            - name: http
              containerPort: 8080
        - name: mesh
          image: cloudflare/mesh:latest
          env:
            - name: MESH_NODE_TOKEN
              valueFrom:
                secretKeyRef:
                  name: cloudflare-mesh-sidecar
                  key: MESH_NODE_TOKEN
            - name: SRCNAT_ENABLED
              value: "true"
          securityContext:
            capabilities:
              add:
                - NET_ADMIN
                - NET_RAW
          volumeMounts:
            - name: warp-data
              mountPath: /var/lib/cloudflare-warp
            - name: dev-net-tun
              mountPath: /dev/net/tun
      volumes:
        - name: dev-net-tun
          hostPath:
            path: /dev/net/tun
            type: CharDevice
  volumeClaimTemplates:
    - metadata:
        name: warp-data
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: cloudflare-mesh-sidecar
spec:
  selector:
    app: cloudflare-mesh-sidecar
  ports:
    - name: http
      port: 8080
      targetPort: http
```

### 3. Verify the sidecar

```sh
kubectl apply -f cloudflare-mesh-sidecar.yaml
kubectl rollout status statefulset/cloudflare-mesh-sidecar
kubectl exec cloudflare-mesh-sidecar-0 -c mesh -- warp-cli status
```

## Runtime configuration

| Parameter | Description |
| --- | --- |
| `MESH_NODE_TOKEN` | **Required** for initial registration. Create the token under **Networking** > **Mesh** in the [Cloudflare dashboard ↗︎](https://dash.cloudflare.com/?to=/:account/mesh), or via the [API](https://developers.cloudflare.com/api/resources/zero_trust/subresources/tunnels/subresources/warp_connector/methods/create/). |
| `SRCNAT_ENABLED` | Controls [source NAT](#source-nat). Defaults to `true`. Accepts `true`, `false`, `1`, or `0`. |
| `/var/lib/cloudflare-warp` | Stores registration state. Persist this path with a volume to maintain a stable Mesh identity across container recreation. |

<details>

<summary>

Required capabilities and devices

</summary>

| Capability / device | Why it is needed |
| --- | --- |
| <code>NET_ADMIN</code> | Creates and configures the tunnel interface, routing, and nftables rules. |
| <code>NET_RAW</code> | Enables raw-socket operations such as ICMP. Docker normally grants this capability by default, but it is declared explicitly here. |
| <code>/dev/net/tun</code> | Creates the WARP TUN interface. |
| IP-forwarding sysctls | Required when the node forwards traffic for routed subnets. |

</details>

## Source NAT

Source NAT (masquerading) is enabled by default (`SRCNAT_ENABLED=true`). When a Mesh node receives traffic from the Cloudflare edge and forwards it to a destination on the local network, it translates the source IP from the Mesh CGNAT address (`100.96.x.x`) to the node's own local interface IP. This ensures return traffic routes correctly without requiring static routes in your VPC or on-premise network.

Set `SRCNAT_ENABLED=false` only if the attached networks already have return routes to the Mesh IP range (`100.96.0.0/12`). For more details on return traffic routing, refer to [Routes](https://developers.cloudflare.com/mesh/features/routes/#return-traffic-routing).

## High availability on Kubernetes

MASQUE required

This feature requires that the [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) of the Mesh node is configured to use [MASQUE](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#device-tunnel-protocol), the default protocol for the Cloudflare One Client. It does not work if the device profile uses WireGuard instead.

For [high availability](https://developers.cloudflare.com/mesh/features/high-availability/) with CIDR routes:

1. Use the same Mesh node token across multiple replicas.
2. Give each Pod its own `PersistentVolumeClaim`.

Cloudflare operates replicas in active-passive mode. If the active replica goes offline, traffic fails over to a standby automatically. A single replica provides no redundancy.

## Hostname routes

Containers support [hostname routing](https://developers.cloudflare.com/mesh/features/routes/#hostname-routes). To resolve Kubernetes Services through a hostname route, make sure the hostname matches the cluster's actual DNS suffix. The default is `cluster.local`, producing Service names like `service.namespace.svc.cluster.local`.

MASQUE required

This feature requires that the [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) of the Mesh node is configured to use [MASQUE](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#device-tunnel-protocol), the default protocol for the Cloudflare One Client. It does not work if the device profile uses WireGuard instead.

## Site-to-site networking

Deploy a separate Mesh node container at each site with a separate node token for each node identity. Each node should advertise its locally reachable subnet as a [CIDR route](https://developers.cloudflare.com/mesh/features/routes/). Configure each site's router or workloads to send traffic for the remote subnet through the local Mesh node.

With `SRCNAT_ENABLED=true`, destinations see the Mesh node's local address. With source NAT disabled, the attached networks require return routes through their Mesh nodes.

## Troubleshooting

### Node registers as a regular Cloudflare One Client device

Confirm that the correct Mesh node token is set in `MESH_NODE_TOKEN`. Existing registration state in the persistent volume takes precedence — remove the volume only when you intentionally want to discard that registration and create a new identity.

### `warp-cli status` remains Connecting

Check the token, device profile, Gateway proxy, Split Tunnel configuration, outbound firewall connectivity, and container logs:

```sh
docker logs cloudflare-mesh
```

### A Kubernetes Service cannot be resolved

Confirm that the [hostname route](https://developers.cloudflare.com/mesh/features/routes/#hostname-routes) matches the cluster's actual DNS suffix. The usual default is `cluster.local`, producing Service names such as `service.namespace.svc.cluster.local`.

### A hostname request arrives but no response returns

Check source NAT and return routing first. Verify `SRCNAT_ENABLED` is set to `true` or that your network has return routes to the Mesh IP range.

### Check node status

```sh
docker exec -it cloudflare-mesh warp-cli status
```

```sh
kubectl exec cloudflare-mesh-0 -- warp-cli status
```

## Next steps

- [**Add routes**](https://developers.cloudflare.com/mesh/features/routes/) — Make subnets behind the containerized node reachable from any device on your Mesh.
- [**Enable high availability**](https://developers.cloudflare.com/mesh/features/high-availability/) — Run multiple replicas for production resilience.
- [**Connect from Workers**](https://developers.cloudflare.com/workers-vpc/examples/connect-to-cloudflare-mesh/) — Use VPC Network bindings to reach private services from Cloudflare Workers.
- [**Tips and best practices**](https://developers.cloudflare.com/mesh/best-practices/) — Cloud VPC configuration, MTU tuning, and running alongside Cloudflare Tunnel.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/#page","headline":"Run Mesh in Docker / Kubernetes","description":"Run a Cloudflare Mesh node as a Docker container for Docker Compose, Kubernetes, and CI/CD environments.","url":"https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/og.png?v=164eeb2486ebbcab","dateModified":"2026-10-29","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks","Containers","Docker","Kubernetes"]}
```

---

---
description: Install a Cloudflare Mesh node on Debian, Ubuntu, or RHEL, and learn what each install command does.
title: Run Mesh on Linux
image: https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/og.png?v=5fb13a643703568c
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Run Mesh on Linux

Last updated Oct 29, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

A Mesh node is a Linux server that runs the Cloudflare One Client (`cloudflare-warp` package) in headless mode. The node joins your Mesh with its own Mesh IP. It can also [route traffic to a private subnet](https://developers.cloudflare.com/mesh/features/routes/) behind it.

Use this guide to install a Mesh node directly on a Linux host. To run a Mesh node without installing packages on the host, refer to [Run Mesh in Docker / Kubernetes](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/).

## Supported distributions

Mesh nodes support the following Linux distributions and hardware:

| **OS version** | RHEL 9 <sup>[1](#user-content-fn-1)</sup>, RHEL 10, Debian 12, Debian 13, Fedora 43, Fedora 44, Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, Ubuntu 26.04 LTS |
| --- | --- |
| **Processor** | AMD64 / x86-64 or ARM64 / AArch64 |
| **vCPU** | 3 minimum, 4 recommended |
| **RAM without a desktop** | 1 GB minimum, 2 GB recommended (for example, Ubuntu Server) |
| **RAM with a desktop** | 4 GB minimum, 8 GB recommended (for example, Ubuntu GNOME) |
| **Disk space** | 250 MiB minimum, 500 MiB recommended |
| **Network interface type** | Wi-Fi or LAN |
| **MTU** | 1381 bytes recommended <sup>[2](#user-content-fn-2)</sup> |

## Footnotes

1. On RHEL 9 and later, enable the [Extra Packages for Enterprise Linux (EPEL) ↗︎](https://docs.fedoraproject.org/en-US/epel/) repository before installing `cloudflare-warp`. EPEL provides dependencies required by the client UI. For the RHEL commands, refer to [Getting started with EPEL ↗︎](https://docs.fedoraproject.org/en-US/epel/getting-started/). [↩](#user-content-fnref-1)
2. Minimum 1281 bytes with [Path MTU Discovery](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/mdm-deployment/path-mtu-discovery/) [↩](#user-content-fnref-2)

Cloudflare One Client version 2026.6.822.0 and later support Cloudflare Mesh on RHEL 9 and RHEL 10. For support dates, refer to the [support lifecycle](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/download/support-lifecycle/#red-hat-enterprise-linux-rhel).

## Prerequisites

Before you install the client, create a Mesh node and get its token.

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. Select **Add participant** > **Add node**.
3. Enter a name for your node (for example, `web-server` or `staging-db`).
4. Select **Create node**.
5. Select **Debian / Ubuntu** or **RHEL**. The dashboard displays the install and registration commands for the node. The registration command includes the node token.

With an API token that has either `Cloudflare One Connectors Write` or `Cloudflare One Connector: WARP Write` permission, create a node and retrieve its connector token:

```bash
set -euo pipefail

NODE_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/warp_connector" \
		--request POST \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
		--header "Content-Type: application/json" \
		--data '{"name":"web-server"}'
)

jq -e '.success == true and (.result.id | type == "string")' \
	<<< "$NODE_RESPONSE" > /dev/null
NODE_ID=$(jq -r '.result.id' <<< "$NODE_RESPONSE")

TOKEN_RESPONSE=$(
	curl --fail-with-body --silent --show-error \
		"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/warp_connector/$NODE_ID/token" \
		--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
)

MESH_NODE_TOKEN=$(jq -er \
	'select(.success == true) | .result | select(type == "string" and length > 0)' \
	<<< "$TOKEN_RESPONSE")
```

Install `jq`, then set `ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN` before running the commands. The commands stop on an HTTP or API error. Do not continue until they return zero and set `NODE_ID` and `MESH_NODE_TOKEN`. If token retrieval fails after node creation, retry only the token request with the existing `NODE_ID`. Do not rerun the node creation request.

Note

Mesh nodes can also be managed with Terraform using the [`cloudflare_zero_trust_tunnel_warp_connector` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_warp_connector) resource. To manage node configuration, use [`cloudflare_zero_trust_tunnel_warp_connector_config` ↗︎](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_warp_connector_config).

If this is your first Mesh node, configure the [required account settings](https://developers.cloudflare.com/mesh/get-started/#required-account-settings). The dashboard wizard configures them for new accounts.

MASQUE required

This feature requires that the [device profile](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/) of the Mesh node is configured to use [MASQUE](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/settings/#device-tunnel-protocol), the default protocol for the Cloudflare One Client. It does not work if the device profile uses WireGuard instead.

Caution

Treat the node token as a secret. Anyone with the token can register a host as this node. Do not commit tokens to source control or share them in tickets or chat.

## 1. Install the client

Install the `cloudflare-warp` package from the Cloudflare package repository. Choose the section for your distribution.

### Debian and Ubuntu

1. Add the Cloudflare package signing key:

   ```sh
   curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
   ```

   `apt` uses this key to verify that packages come from Cloudflare.
2. Add the Cloudflare repository:

   ```sh
   echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(. /etc/os-release && echo $VERSION_CODENAME) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
   ```

   The `$VERSION_CODENAME` variable resolves to your release codename (for example, `noble` or `trixie`). This selects the package build for your release.
3. Install the package:

   ```sh
   sudo apt-get update && sudo apt-get install -y cloudflare-warp
   ```

### RHEL

1. Enable the [Extra Packages for Enterprise Linux (EPEL) ↗︎](https://docs.fedoraproject.org/en-US/epel/) repository. EPEL provides dependencies that the Cloudflare One Client needs on RHEL 9 and later. EPEL packages can depend on the CodeReady Builder (CRB) repository, so turn on CRB first.

   The `epel-release` package is not in the default RHEL repositories. Turn on CodeReady Builder, then install the EPEL release package for your RHEL version:

   ```sh
   sudo subscription-manager repos --enable codeready-builder-for-rhel-$(rpm -E %rhel)-$(arch)-rpms &&
   sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E %rhel).noarch.rpm
   ```

   The `subscription-manager` command requires a host registered with Red Hat Subscription Management. On pay-as-you-go cloud images that use Red Hat Update Infrastructure (RHUI), the CodeReady Builder repository has a different name. Refer to your cloud provider's documentation to turn it on, then run the `dnf install` command.

   On RHEL-compatible distributions, such as Rocky Linux and AlmaLinux, `epel-release` is in the default repositories. Turn on CRB, then install it:

   ```sh
   sudo dnf config-manager --set-enabled crb &&
   sudo dnf install -y epel-release
   ```

2. Add the Cloudflare repository:

   ```sh
   curl -fsSL https://pkg.cloudflareclient.com/cloudflare-warp-ascii.repo | sudo tee /etc/yum.repos.d/cloudflare-warp.repo
   ```

   The repository file points `dnf` to the package build for your RHEL version and to the Cloudflare signing key.
3. Install the package:

   ```sh
   sudo dnf install -y cloudflare-warp
   ```

Note

Install from the repository instead of downloading the standalone `.rpm` file. The repository resolves dependencies such as `nss-tools`, which RHEL does not install by default.

Rocky Linux and AlmaLinux are not in [Supported distributions](#supported-distributions). Cloudflare does not test Mesh nodes on them.

## 2. Register and connect the node

To register the host as your Mesh node and connect it, run the following command. Replace `<MESH_NODE_TOKEN>` with the node token from the [prerequisites](#prerequisites).

```sh
sudo warp-cli --accept-tos connector new <MESH_NODE_TOKEN> && sudo warp-cli --accept-tos connect
```

This command runs two `warp-cli` subcommands:

| Command | Purpose |
| --- | --- |
| `connector new` | Registers the host as the Mesh node that the token identifies. It does not enroll a user device. |
| `connect` | Connects the node to Cloudflare. The client reconnects automatically after reboots. |
| `--accept-tos` flag | Accepts the Cloudflare One Client terms of service without an interactive prompt. |

If you use the same token on more than one host, each host joins as a replica of the same node. For more information, refer to [High availability](https://developers.cloudflare.com/mesh/features/high-availability/).

## 3. Verify the node

1. On the node, check the connection status:

   ```sh
   warp-cli status
   ```

   ```txt
   Status update: Connected
   ```

2. In the Cloudflare dashboard, go to **Networking** > **Mesh**. Confirm that the node shows as **Online**, and note its **Mesh IP**.
3. From an enrolled client device, test a service on the node. For example, to test SSH:

   ```sh
   nc -vz <MESH_IP> 22
   ```

   A **Connected** status does not prove that peers can reach the node. Test the application protocol you intend to use.

## Turn on IP forwarding for routes

IP forwarding lets the node pass packets between the Mesh and its local network. Turn it on only if the node will advertise [CIDR routes](https://developers.cloudflare.com/mesh/features/routes/) to make a subnet behind it reachable. You do not need it to reach the node by its own Mesh IP. You can turn it on at any time, before or after you connect the node.

To turn on forwarding and keep it across reboots, run:

```sh
printf 'net.ipv4.ip_forward = 1\nnet.ipv6.conf.all.forwarding = 1\nnet.ipv6.conf.all.accept_ra = 2\n' | sudo tee /etc/sysctl.d/99-zzz-cloudflare-warp-connector.conf &&
sudo sysctl --system
```

This command writes three kernel settings to a file in `/etc/sysctl.d/`, then reloads all settings:

| Setting | Purpose |
| --- | --- |
| `net.ipv4.ip_forward = 1` | Forwards IPv4 packets between interfaces. |
| `net.ipv6.conf.all.forwarding = 1` | Forwards IPv6 packets between interfaces. |
| `net.ipv6.conf.all.accept_ra = 2` | Keeps accepting IPv6 router advertisements after forwarding is on. Without it, the host can lose IPv6 routes. |

The `99-zzz-` prefix makes the file load last, so other files in `/etc/sysctl.d/` cannot override it.

If the host runs in a cloud VPC, you may also need provider settings, such as turning off source/destination checks on AWS. For more information, refer to [Cloud VPC deployments](https://developers.cloudflare.com/mesh/best-practices/#cloud-vpc-deployments).

## Manage the node

### Check status and reconnect

| Command | Purpose |
| --- | --- |
| `warp-cli status` | Shows the current connection status. |
| `warp-cli connect` | Reconnects the node. |
| `warp-cli disconnect` | Disconnects the node without deregistering. |
| `warp-cli --version` | Shows the installed client version. |

### Update the client

Updating the client briefly disconnects the node. If you run [high availability](https://developers.cloudflare.com/mesh/features/high-availability/) replicas, traffic fails over to a standby.

```sh
sudo apt-get update && sudo apt-get install --only-upgrade -y cloudflare-warp
```

```sh
sudo dnf upgrade -y cloudflare-warp
```

After the update, run `warp-cli status` to confirm the node reconnected.

### View logs

The client runs as the `warp-svc` systemd service. To view recent service logs, run:

```sh
sudo journalctl -u warp-svc --since "15 minutes ago"
```

To collect a full diagnostic bundle for Cloudflare support, run `warp-diag`. For more information, refer to [Diagnostic logs](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/troubleshooting/diagnostic-logs/).

### Remove the node

1. On the host, delete the registration:

   ```sh
   sudo warp-cli registration delete
   ```

2. Uninstall the package:

   ```sh
   sudo apt-get remove -y cloudflare-warp
   ```

   ```sh
   sudo dnf remove -y cloudflare-warp
   ```

3. (Optional) If you turned on IP forwarding for this node, remove the setting:

   ```sh
   sudo rm /etc/sysctl.d/99-zzz-cloudflare-warp-connector.conf && sudo sysctl --system
   ```

4. In the Cloudflare dashboard, go to **Networking** > **Mesh** and delete the node. Skip this step if other replicas still use the node.

## Troubleshooting

### The node shows as Offline

Run `warp-cli status` on the node. If the status is not `Connected`:

- Run `warp-cli connect`.
- Confirm that your firewall allows the [Cloudflare One Client ports and IPs](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/firewall/).
- Review the [service logs](#view-logs).

### The node registers as a regular client device

Confirm that you ran `warp-cli connector new` with a Mesh node token. If the host was enrolled as a user device before, run `sudo warp-cli registration delete`, then register it again with the node token.

### Routed subnets are not reachable

Confirm that [IP forwarding](#turn-on-ip-forwarding-for-routes) is on:

```sh
sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding
```

Both values must be `1`. Then confirm that the destination network can route return traffic to the Mesh IP range (`100.96.0.0/12`). For more information, refer to [Return traffic routing](https://developers.cloudflare.com/mesh/features/routes/#return-traffic-routing).

### Package install fails on RHEL

Run `dnf repolist` and confirm that EPEL and CodeReady Builder (`crb` on Rocky Linux and AlmaLinux) are enabled. For more information, refer to the [EPEL getting started guide ↗︎](https://docs.fedoraproject.org/en-US/epel/getting-started/).

For general client issues, refer to [Troubleshoot the Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/troubleshooting/).

## Next steps

- [**Add routes**](https://developers.cloudflare.com/mesh/features/routes/) — Make subnets behind the node reachable from any participant on your Mesh.
- [**Enable high availability**](https://developers.cloudflare.com/mesh/features/high-availability/) — Run multiple replicas for production resilience.
- [**Tips and best practices**](https://developers.cloudflare.com/mesh/best-practices/) — Cloud VPC configuration, DNS servers, and running alongside Cloudflare Tunnel.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/#page","headline":"Run Mesh on Linux","description":"Install a Cloudflare Mesh node on Debian, Ubuntu, or RHEL, and learn what each install command does.","url":"https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/guides/run-mesh-on-linux/og.png?v=5fb13a643703568c","dateModified":"2026-10-29","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks","Linux"]}
```

---

---
description: Recommended practices for reliable Cloudflare Mesh deployments.
title: Best practices
image: https://developers.cloudflare.com/mesh/best-practices/og.png?v=af0dc09d7e0c29fc
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Best practices

Last updated Sep 16, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/best-practices/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Operational guidance for managing Cloudflare Mesh deployments — updating the client, configuring cloud providers, running alongside Cloudflare Tunnel, and common troubleshooting.

## Update a Mesh node

Updating a Mesh node means updating the `cloudflare-warp` package on the Linux host. The node briefly disconnects during the update, which interrupts traffic routed through it. If you have [high availability](https://developers.cloudflare.com/mesh/features/high-availability/) enabled, traffic fails over to a standby replica automatically.

1. Check the current version:

   ```sh
   warp-cli --version
   ```

2. Update the package:

   ```sh
   sudo apt-get update && sudo apt-get install --only-upgrade cloudflare-warp
   ```

1. Check the current version:

   ```sh
   warp-cli --version
   ```

2. Update the package:

   ```sh
   sudo yum update cloudflare-warp
   ```

3. Verify the node has reconnected:

   ```sh
   warp-cli status
   ```

   You should see `Status update: Connected` in the output.

## Make IP forwarding persistent

IP forwarding allows a Mesh node to act as a gateway, forwarding packets between its network interface and the Cloudflare network. This is only required if the node advertises [CIDR routes](https://developers.cloudflare.com/mesh/features/routes/) — if you are only reaching the node by its Mesh IP, forwarding is not needed.

Older installations may have used `sysctl -w` for IP forwarding, which does not persist across reboots. If your node loses route connectivity after a server restart, run the following to make forwarding permanent:

```sh
printf 'net.ipv4.ip_forward = 1\nnet.ipv6.conf.all.forwarding = 1\nnet.ipv6.conf.all.accept_ra = 2\n' | sudo tee /etc/sysctl.d/99-zzz-cloudflare-warp-connector.conf && sudo sysctl --system
```

You can verify the settings are active with:

```sh
sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding net.ipv6.conf.all.accept_ra
```

New installations include this step automatically.

## Cloud VPC deployments

When deploying Mesh nodes in a cloud VPC, you may need to configure additional provider settings so the node can forward traffic for other devices on the subnet.

### Google Cloud Platform (GCP)

[Enable IP forwarding ↗︎](https://cloud.google.com/vpc/docs/using-routes#canipforward) on the VM instance where you installed the Mesh node.

### Amazon Web Services (AWS)

- Disable [source/destination checking ↗︎](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) on the EC2 instance.
- In your [subnet route table ↗︎](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-route-tables.html), add a route for Mesh traffic (for example, `100.96.0.0/12`) pointing to the EC2 instance.

### Microsoft Azure

- [Enable IP forwarding ↗︎](https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-network-interface?tabs=azure-portal#enable-or-disable-ip-forwarding) on the network interface of the VM.
- Add a [user-defined route ↗︎](https://learn.microsoft.com/en-us/azure/virtual-network/manage-route-table) for Mesh traffic pointing to the VM's private IP.

## Running Mesh on a DNS server

Mesh nodes run in [Traffic and DNS mode](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/modes/), which redirects DNS queries on the host to Cloudflare Gateway. This will conflict with DNS services running on the same machine (for example, Active Directory DNS, Pi-hole, Unbound, BIND, or dnsmasq).

If your server runs a DNS service, do not install the Mesh node on that host. Instead, install the node on a separate machine on the same subnet and use [CIDR routes](https://developers.cloudflare.com/mesh/features/routes/) to make the DNS server reachable.

## Running Mesh alongside other VPN or mesh software

The Cloudflare One Client creates a virtual network interface and manages the system routing table. Other software that does the same — Tailscale, WireGuard, OpenVPN, Cisco AnyConnect, GlobalProtect, ZScaler, Netskope, or any traditional VPN client — will compete for control of routing. Running them simultaneously causes unpredictable behavior: traffic may flow through the wrong tunnel or fail entirely.

If you are migrating to Cloudflare Mesh from another solution:

1. Uninstall or disable the other client (for example, `sudo systemctl stop tailscaled && sudo systemctl disable tailscaled` on Linux, or quit the application from the system tray on macOS/Windows).
2. Restart the machine so the Cloudflare One Client's virtual network interface takes priority in the routing table.
3. Verify connectivity by running `warp-cli status` and pinging a Mesh IP.

This applies to both Mesh nodes and client devices.

## Running Mesh with Cloudflare Tunnel

A Mesh node (`warp-cli`) and [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/) (`cloudflared`) can run on the same Linux host. This is useful when you want to use the Mesh node as a gateway for your private network while also using Cloudflare Tunnel to publish specific applications.

The Mesh node captures outbound traffic and routes it through Cloudflare, which can prevent `cloudflared` from making its required outbound connections. To resolve this, use [Split Tunnels](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/route-traffic/split-tunnels/) to exclude the hostnames and IPs listed in [Tunnel with firewall](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/configure-tunnels/tunnel-with-firewall/#required-for-tunnel-operation).

Note

Split Tunnels is the only supported method of running both connectors on the same machine. The Mesh node's kernel-level integration overrides manual routing configurations (`ip route add`, `iptables`).

## Routing between Mesh and Cloudflare WAN

To route traffic between Cloudflare Mesh and [Cloudflare WAN](https://developers.cloudflare.com/cloudflare-wan/) (for example, reaching a Mesh node from a WAN-connected site or vice versa), your account must be on [Unified Routing mode](https://developers.cloudflare.com/cloudflare-wan/reference/traffic-steering/#unified-routing). Unified Routing uses a single routing fabric for all connection types (Cloudflare One Client, Cloudflare Tunnel, IPsec, GRE, CNI). Without it, Mesh and WAN connections cannot exchange traffic.

## Connect Workers to Mesh

Cloudflare Workers can connect to destinations routed through Cloudflare Mesh using [VPC Network bindings](https://developers.cloudflare.com/workers-vpc/configuration/vpc-networks/). Use `cf1:network` to select your account's default virtual network, or `cf1:vnet:<UUID>` to select a specific configured virtual network.

The same binding also handles outbound traffic to public Internet destinations: requests egress through [Cloudflare Gateway](https://developers.cloudflare.com/cloudflare-one/traffic-controls/), so your existing Zero Trust traffic policies are enforced and Worker traffic appears in Gateway DNS, HTTP, and Network logs alongside the rest of your traffic.

For setup instructions and examples, refer to [Connect Workers to Cloudflare Mesh](https://developers.cloudflare.com/workers-vpc/examples/connect-to-cloudflare-mesh/).

## Source IPs for Cloudflare services

When Cloudflare services (such as [Load Balancing](https://developers.cloudflare.com/load-balancing/) health checks or [Workers](https://developers.cloudflare.com/workers/)) send traffic to your private network through a Mesh node, the traffic originates from the Cloudflare source IP range (default `100.64.0.0/12`). You may need to [configure Cloudflare source IPs](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-wan/configuration/how-to/configure-cloudflare-source-ips/) to avoid IP conflicts.

## MTU and packet fragmentation

Mesh nodes use encapsulation to route traffic, which adds overhead to each packet. This is especially relevant for traffic between two Mesh participants, where the packet may be encapsulated twice (once by the sending node, and again by Cloudflare before delivery to the receiving side).

If source devices send packets near the maximum size (1,460 bytes or more), the double encapsulation can push packets over 1,500 bytes, causing them to be dropped.

### Recommendations

- Set the MTU on source devices (servers, cameras, IoT devices) to **1,280 bytes** to ensure packets fit after encapsulation.
- For TCP-only traffic, apply MSS clamping on your router with a value of **1,240 bytes** (1,280 MTU - 20 byte IP header - 20 byte TCP header).
- Modern applications using [Path MTU Discovery (PMTUD) ↗︎](https://www.cloudflare.com/learning/network-layer/what-is-mtu/) typically handle this automatically.

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/best-practices/#page","headline":"Best practices","description":"Recommended practices for reliable Cloudflare Mesh deployments.","url":"https://developers.cloudflare.com/mesh/best-practices/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/best-practices/og.png?v=af0dc09d7e0c29fc","dateModified":"2026-09-16","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```

---

---
description: Review Cloudflare Mesh availability and platform requirements.
title: Platform
image: https://developers.cloudflare.com/mesh/platform/og.png?v=e51b50ef2cf8138c
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Platform

Last updated Sep 16, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/platform/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Cloudflare Mesh is available in beta to Cloudflare One accounts, including accounts on the Free plan.

## Platform requirements

- Mesh nodes require a [supported Linux distribution](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/download/#linux) or the [`cloudflare/mesh` container image](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/).
- Client devices can use any [operating system supported by the Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/download/).
- Mesh nodes must use the MASQUE device tunnel protocol. Hostname routes, IPv6 CIDR routes, and high availability do not work with WireGuard.
- Using Cloudflare Mesh with Cloudflare WAN requires [Unified Routing mode](https://developers.cloudflare.com/cloudflare-wan/reference/traffic-steering/#unified-routing).

For deployment recommendations and interoperability constraints, refer to [Best practices](https://developers.cloudflare.com/mesh/best-practices/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/platform/#page","headline":"Platform","description":"Review Cloudflare Mesh availability and platform requirements.","url":"https://developers.cloudflare.com/mesh/platform/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/platform/og.png?v=e51b50ef2cf8138c","dateModified":"2026-09-16","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```

---

---
description: Diagnose offline Mesh participants, unreachable Mesh IPs, one-way site traffic, private subnet routes, and service failures.
title: Troubleshoot Cloudflare Mesh connectivity
image: https://developers.cloudflare.com/mesh/troubleshooting/og.png?v=8ef8f04ed37b667a
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/mesh/llms.txt  
> Use this file to discover all available pages before exploring further.

# Troubleshoot Cloudflare Mesh connectivity

Last updated Oct 29, 2026|Copy as Markdown| [View as Markdown](https://developers.cloudflare.com/mesh/troubleshooting/index.md)| [Agent setup](https://developers.cloudflare.com/agent-setup/)

Use this guide when a Mesh node or client device is offline, a Mesh IP does not respond, or traffic between private subnets fails. A participant marked **Online** is connected to Cloudflare. That status does not confirm the service or return path works.

## Identify the failing connection

1. In the Cloudflare dashboard, go to **Networking** > **Mesh**. Check the source and destination participant status and record the destination Mesh IP. [Go to **Mesh** ↗](https://dash.cloudflare.com/?to=/:account/mesh)
2. From the source device, test a service that you know is listening on the destination. For example, test SSH on TCP port `22`. On macOS or Linux, install `nc` if it is not already available:

   ```sh
   nc -vz <DESTINATION-IP> 22
   ```

   ```powershell
   Test-NetConnection <DESTINATION-IP> -Port 22
   ```

3. Replace `<DESTINATION-IP>` with the Mesh IP of a participant or the private IP of a host behind a node. Use your service's port if it differs from `22`. Choose the symptom that matches the failed test.

Do not use `ping` as the only test. It requires the [ICMP Gateway proxy](https://developers.cloudflare.com/cloudflare-one/traffic-controls/proxy/), even when TCP or UDP traffic works.

## Node or device shows offline

An offline participant cannot carry Mesh traffic. First check its Cloudflare One Client connection:

1. On a Linux node, run:

   ```sh
   warp-cli status
   ```

2. If the output does not show `Status update: Connected`, run `warp-cli connect` and check its status again.
3. If it still does not connect, verify that the host can reach the [required Cloudflare One Client IPs and ports](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/deployment/firewall/). Review the [client diagnostic logs](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/troubleshooting/diagnostic-logs/) for enrollment or connection errors.

For a laptop or phone that cannot enroll or connect, follow [Troubleshoot the Cloudflare One Client](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/troubleshooting/). If a container node connects as a regular client device, verify its connector token and persistent registration state in [Run Mesh in containers](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/#troubleshooting).

## Participant is online, but its Mesh IP is unreachable

The connection to Cloudflare is healthy, but traffic may bypass the Mesh tunnel or be blocked before reaching the service:

1. Confirm both participants are enrolled in the same Cloudflare One account and use the destination's assigned Mesh IP. Check [Required account settings](https://developers.cloudflare.com/mesh/get-started/#required-account-settings), including unique device IPs and allowing Cloudflare One traffic to reach enrolled devices.
2. On the source and destination, check the applied [device profiles](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/configure/device-profiles/). Mesh nodes must use Traffic and DNS mode. In Split Tunnels **Include mode**, include `100.96.0.0/12`. In **Exclude mode**, make sure neither that range nor a parent such as `100.64.0.0/10` is excluded. Use your custom device IP range if you changed the default.
3. Confirm that the [Gateway proxy](https://developers.cloudflare.com/cloudflare-one/traffic-controls/proxy/) is on for the test protocol. ICMP is optional, but TCP or UDP proxying must be on for those services.
4. Confirm the destination service listens on the Mesh IP or all interfaces and that its host firewall allows the source Mesh IP and port. Review [Gateway network policies](https://developers.cloudflare.com/cloudflare-one/traffic-controls/network-policies/) and [Network logs](https://developers.cloudflare.com/cloudflare-one/insights/logs/dashboard-logs/gateway-logs/#network) for a blocked request.

A service bound only to the host's separate local-network IP will not accept a connection to its Mesh IP. If the IP responds but the application fails, check the service configuration and port before changing Mesh routes.

## Mesh IP works, but a private subnet does not

Reaching a node by Mesh IP does not make the hosts behind it reachable. A routed subnet also requires a CIDR route, forwarding, and a return path:

1. On the destination node's **Routes** tab, confirm that a [CIDR route](https://developers.cloudflare.com/mesh/features/routes/#add-a-route) covers the private destination IP and points to that node.
2. On the source participant, confirm that the destination CIDR routes through Cloudflare in its [Split Tunnels](https://developers.cloudflare.com/mesh/features/routes/#configure-split-tunnels/) settings. If the source is a host behind another node, confirm its router sends the destination CIDR to the local node.
3. On the destination Linux node, check IPv4 forwarding:

   ```sh
   sysctl net.ipv4.ip_forward
   ```

   If the result is `0`, follow [Make IP forwarding persistent](https://developers.cloudflare.com/mesh/best-practices/#make-ip-forwarding-persistent/). Cloud virtual machines may also need [provider-specific forwarding settings](https://developers.cloudflare.com/mesh/best-practices/#cloud-vpc-deployments/).
4. On the destination node, check that UFW, firewalld, nftables, or another host firewall allows forwarded traffic between the Cloudflare One Client and local network interfaces. Check cloud firewall rules or security groups as well.
5. Check the destination host firewall and return route. For a source with a Mesh IP, route the Mesh device IP range through the destination node. For a source on another private subnet, route that remote subnet through the destination node. If the node is the local default gateway, separate static return routes are not needed.

Container nodes can use [source NAT](https://developers.cloudflare.com/mesh/guides/run-mesh-in-containers/#source-nat/) instead of return routes to Mesh IP clients. Check the container setting before changing the router.

## One site can reach the other, but not vice versa

Site-to-site traffic needs the same configuration in both directions. A route at one site does not automatically configure the other:

1. Confirm each node advertises **its own** local subnet as a CIDR route.
2. Confirm each node's effective Split Tunnel configuration sends the **other** site's subnet through Cloudflare.
3. Confirm each site router sends traffic for the remote subnet to its **local node IP**. Check the reverse route for responses on both sites.
4. Check each node's forwarding firewall rules in both directions.
5. Test a listening service from a host behind each node. Check both destination firewalls and Gateway network policies if only one direction fails.

For a complete two-site example, refer to [Connect two private networks with Cloudflare Mesh](https://developers.cloudflare.com/mesh/guides/connect-sites/).

## Private IP works, but the hostname does not

CIDR routing does not create DNS records. Confirm the hostname resolves to the correct private IP and that the client can reach the DNS resolver. Test the private IP first to isolate DNS from network routing.

For a [Mesh hostname route](https://developers.cloudflare.com/mesh/features/routes/#hostname-routes), also confirm that the node uses MASQUE and that the client sends the DNS query to Cloudflare Gateway instead of using Local Domain Fallback. Follow the hostname-route DNS instructions for your resolver arrangement.

## Connection fails only for large packets

Encapsulation can cause larger packets to exceed the available path maximum transmission unit (MTU). If a small service request works but larger responses stall, follow the [MTU and packet fragmentation recommendations](https://developers.cloudflare.com/mesh/best-practices/#mtu-and-packet-fragmentation/).

## Check logs

Use [Gateway Network logs](https://developers.cloudflare.com/cloudflare-one/insights/logs/dashboard-logs/gateway-logs/#network) to inspect the source, destination, port, and policy action. If a failed attempt has no entry, check Split Tunnels and the [Gateway traffic logging setting](https://developers.cloudflare.com/cloudflare-one/insights/logs/dashboard-logs/gateway-logs/#selective-logging/) before changing policies. To diagnose a node that cannot connect, collect [Cloudflare One Client diagnostic logs](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/cloudflare-one-client/troubleshooting/diagnostic-logs/).

Was this helpful?

YesNo

## On this page

[![](https://developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/mesh/troubleshooting/#page","headline":"Troubleshoot Cloudflare Mesh connectivity","description":"Diagnose offline Mesh participants, unreachable Mesh IPs, one-way site traffic, private subnet routes, and service failures.","url":"https://developers.cloudflare.com/mesh/troubleshooting/","inLanguage":"en","image":"https://developers.cloudflare.com/mesh/troubleshooting/og.png?v=8ef8f04ed37b667a","dateModified":"2026-10-29","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["Private networks"]}
```
