---
layout: docs
page_title: Mesh - Configuration Entry Reference
description: >-
  The mesh configuration entry kind defines global default settings like TLS version requirements for proxies inside the service mesh. Use the reference guide to learn about `""mesh""` config entry parameters and how to control communication with services outside of the mesh.
---

# Mesh Configuration Entry

The `mesh` configuration entry allows you to define a global default configuration that applies to all service mesh proxies.
Settings in this config entry apply across all namespaces and federated datacenters.

## Sample Configuration Entries

### Mesh-wide TLS Min Version

Enforce that service mesh mTLS traffic uses TLS v1.2 or newer.

<Tabs>
<Tab heading="Consul CE">

<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>

```hcl
Kind = "mesh"
TLS {
  Incoming {
    TLSMinVersion = "TLSv1_2"
  }
}
```

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
  name: mesh
spec:
  tls:
    incoming:
      tlsMinVersion: TLSv1_2
```

```json
{
  "Kind": "mesh",
  "TLS": {
    "Incoming": {
      "TLSMinVersion": "TLSv1_2"
    }
  }
}
```

</CodeTabs>

</Tab>
<Tab heading="Consul Enterprise">

The `mesh` configuration entry can only be created in the `default` namespace and will apply to proxies across **all** namespaces.

<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>

```hcl
Kind      = "mesh"

TLS {
  Incoming {
    TLSMinVersion = "TLSv1_2"
  }
}
```

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
  name: mesh
  namespace: default
spec:
  tls:
    incoming:
      tlsMinVersion: TLSv1_2
```

```json
{
  "Kind": "mesh",
  "Namespace": "default",
  "Partition": "default",
  "TLS": {
    "Incoming": {
      "TLSMinVersion": "TLSv1_2"
    }
  }
}
```

</CodeTabs>

</Tab>
</Tabs>

Note that the Kubernetes example does not include a `partition` field. Configuration entries are applied on Kubernetes using [custom resource definitions (CRD)](/consul/docs/k8s/crds), which can only be scoped to their own partition.

### Mesh Destinations Only

Only allow transparent proxies to dial addresses in the mesh.

<Tabs>
<Tab heading="Consul CE">

<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>

```hcl
Kind = "mesh"
TransparentProxy {
  MeshDestinationsOnly = true
}
```

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
  name: mesh
spec:
  transparentProxy:
    meshDestinationsOnly: true
```

```json
{
  "Kind": "mesh",
  "TransparentProxy": {
    "MeshDestinationsOnly": true
  }
}
```

</CodeTabs>

</Tab>
<Tab heading="Consul Enterprise">

The `mesh` configuration entry can only be created in the `default` namespace and will apply to proxies across **all** namespaces.

<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>

```hcl
Kind      = "mesh"

TransparentProxy {
  MeshDestinationsOnly = true
}
```

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
  name: mesh
  namespace: default
spec:
  transparentProxy:
    meshDestinationsOnly: true
```

```json
{
  "Kind": "mesh",
  "Namespace": "default",
  "Partition": "default",
  "TransparentProxy": {
    "MeshDestinationsOnly": true
  }
}
```

</CodeTabs>

</Tab>
</Tabs>

Note that the Kubernetes example does not include a `partition` field. Configuration entries are applied on Kubernetes using [custom resource definitions (CRD)](/consul/docs/k8s/crds), which can only be scoped to their own partition.

###  Peer Through Mesh Gateways

Set the `PeerThroughMeshGateways` parameter to `true` to route peering control plane traffic through mesh gateways.

<Tabs>
<Tab heading="Consul CE">

<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>

```hcl
Kind = "mesh"
Peering {
  PeerThroughMeshGateways = true
}
```

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
  name: mesh
spec:
  peering:
    peerThroughMeshGateways: true
```

```json
{
  "Kind": "mesh",
  "Peering": {
    "PeerThroughMeshGateways": true
  }
}
```

</CodeTabs>

</Tab>
<Tab heading="Consul Enterprise">

You can only set the `PeerThroughMeshGateways` attribute on `mesh` configuration entries in the `default` partition.
The `default` partition owns the traffic routed through the mesh gateway control plane to Consul servers.

<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>

```hcl
Kind = "mesh"

Peering {
  PeerThroughMeshGateways = true
}
```

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
  name: mesh
  namespace: default
spec:
  peering:
    peerThroughMeshGateways: true
```

```json
{
  "Kind": "mesh",
  "Peering": {
    "PeerThroughMeshGateways": true
  }
}
```

</CodeTabs>

</Tab>
</Tabs>

Note that the Kubernetes example does not include a `partition` field. Configuration entries are applied on Kubernetes using [custom resource definitions (CRD)](/consul/docs/k8s/crds), which can only be scoped to their own partition.

### Request Normalization

Enable options under `HTTP.Incoming.RequestNormalization` to apply normalization to all inbound traffic to mesh proxies.

~> **Compatibility warning**: This feature is available as of Consul CE 1.20.1 and Consul Enterprise 1.20.1, 1.19.2, 1.18.3, and 1.15.15. We recommend upgrading to the latest version of Consul to take advantage of the latest features and improvements.

<CodeTabs tabs={[ "HCL", "Kubernetes YAML", "JSON" ]}>

```hcl
Kind = "mesh"
HTTP {
  Incoming {
    RequestNormalization {
      InsecureDisablePathNormalization = false // default false, shown for completeness
      MergeSlashes = true
      PathWithEscapedSlashesAction = "UNESCAPE_AND_FORWARD"
      HeadersWithUnderscoresAction = "REJECT_REQUEST"
    }
  }
}
```

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
  name: mesh
spec:
  http:
    incoming:
      requestNormalization:
        insecureDisablePathNormalization: false # default false, shown for completeness
        mergeSlashes: true
        pathWithEscapedSlashesAction: UNESCAPE_AND_FORWARD
        headersWithUnderscoresAction: REJECT_REQUEST
```

```json
{
  "Kind": "mesh",
  "HTTP": {
    "Incoming": {
      "RequestNormalization": {
        "InsecureDisablePathNormalization": false,
        "MergeSlashes": true,
        "PathWithEscapedSlashesAction": "UNESCAPE_AND_FORWARD",
        "HeadersWithUnderscoresAction": "REJECT_REQUEST"
      }
    }
  }
}
```

</CodeTabs>

## Available Fields

<ConfigEntryReference
  keys={[
    {
      name: 'apiVersion',
      description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
      hcl: false,
    },
    {
      name: 'Kind',
      description: {
        hcl: 'Must be set to `mesh`',
        yaml: 'Must be set to `Mesh`',
      },
    },
    {
      name: 'Namespace',
      type: `string: "default"`,
      enterprise: true,
      description:
        'Must be set to `default`. The configuration will apply to all namespaces.',
      yaml: false,
    },
    {
      name: 'Partition',
      type: `string: "default"`,
      enterprise: true,
      description:
        'Specifies the name of the admin partition in which the configuration entry applies. Refer to the [Admin Partitions documentation](/consul/docs/enterprise/admin-partitions) for additional information.',
      yaml: false,
    },
    {
      name: 'Meta',
      type: 'map<string|string>: nil',
      description:
        'Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.',
      yaml: false,
    },
    {
      name: 'metadata',
      children: [
        {
          name: 'name',
          description: 'Must be set to `mesh`',
        },
        {
          name: 'namespace',
          enterprise: true,
          description:
            'Must be set to `default`. If running Consul Community Edition, the namespace is ignored (see [Kubernetes Namespaces in Consul CE](/consul/docs/k8s/crds#consul-ce)). If running Consul Enterprise see [Kubernetes Namespaces in Consul Enterprise](/consul/docs/k8s/crds#consul-enterprise) for additional information.',
        },
      ],
      hcl: false,
    },
    {
      name: 'TransparentProxy',
      type: 'TransparentProxyConfig: <optional>',
      description:
        'Controls configuration specific to proxies in `transparent` [mode](/consul/docs/connect/config-entries/service-defaults#mode). Added in v1.10.0.',
      children: [
        {
          name: 'MeshDestinationsOnly',
          type: 'bool: false',
          description: `Determines whether sidecar proxies operating in transparent mode can
                        proxy traffic to IP addresses not registered in Consul's mesh. If enabled, traffic will only be proxied
                        to upstream proxies or mesh-native services. If disabled, requests will be proxied as-is to the
                        original destination IP address. Consul will not encrypt the connection.`,
        },
      ],
    },
    {
      name: 'AllowEnablingPermissiveMutualTLS',
      type: 'bool: false',
      description:
        'Controls whether `MutualTLSMode=permissive` can be set in the `proxy-defaults` and `service-defaults` configuration entries. '
    },
    {
      name: 'ValidateClusters',
      type: 'bool: false',
      description:
        `Controls whether the clusters the route table refers to are validated. The default value is false. When set to
         false and a route refers to a cluster that does not exist, the route table loads and routing to a non-existent
         cluster results in a 404. When set to true and the route is set to a cluster that do not exist, the route table
         will not load.  For more information, refer to
         [HTTP route configuration in the Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route.proto#envoy-v3-api-field-config-route-v3-routeconfiguration-validate-clusters)
         for more details. `,
    },
    {
      name: 'TLS',
      type: 'TLSConfig: <optional>',
      description: 'TLS configuration for the service mesh.',
      children: [
        {
          name: 'Incoming',
          type: 'TLSDirectionConfig: <optional>',
          description: `TLS configuration for inbound mTLS connections targeting
                        the public listener on \`connect-proxy\` and \`terminating-gateway\`
                        proxy kinds.`,
          children: [
            {
              name: 'TLSMinVersion',
              type: 'string: ""',
              description:
                "Set the default minimum TLS version supported. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy v1.22.0 and newer [will default to TLS 1.2 as a min version](https://github.com/envoyproxy/envoy/pull/19330), while older releases of Envoy default to TLS 1.0.",
            },
            {
              name: 'TLSMaxVersion',
              type: 'string: ""',
              description: {
                hcl:
                  "Set the default maximum TLS version supported. Must be greater than or equal to `TLSMinVersion`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy will default to TLS 1.3 as a max version for incoming connections.",
                yaml:
                  "Set the default maximum TLS version supported. Must be greater than or equal to `tls_min_version`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy will default to TLS 1.3 as a max version for incoming connections.",
              },
            },
            {
              name: 'CipherSuites',
              type: 'array<string>: <optional>',
              description: `Set the default list of TLS cipher suites
                            to support when negotiating connections using
                            TLS 1.2 or earlier. If unspecified, Envoy will use a
                            [default server cipher list](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#envoy-v3-api-field-extensions-transport-sockets-tls-v3-tlsparameters-cipher-suites).
                            The list of supported cipher suites can seen in
                            [\`consul/types/tls.go\`](https://github.com/hashicorp/consul/blob/v1.11.2/types/tls.go#L154-L169)
                            and is dependent on underlying support in Envoy. Future
                            releases of Envoy may remove currently-supported but
                            insecure cipher suites, and future releases of Consul
                            may add new supported cipher suites if any are added to
                            Envoy.`,
            },
          ],
        },
        {
          name: 'Outgoing',
          type: 'TLSDirectionConfig: <optional>',
          description: `TLS configuration for outbound mTLS connections dialing upstreams
                        from \`connect-proxy\` and \`ingress-gateway\`
                        proxy kinds.`,
          children: [
            {
              name: 'TLSMinVersion',
              type: 'string: ""',
              description:
                "Set the default minimum TLS version supported. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy v1.22.0 and newer [will default to TLS 1.2 as a min version](https://github.com/envoyproxy/envoy/pull/19330), while older releases of Envoy default to TLS 1.0.",
            },
            {
              name: 'TLSMaxVersion',
              type: 'string: ""',
              description: {
                hcl:
                  "Set the default maximum TLS version supported. Must be greater than or equal to `TLSMinVersion`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy will default to TLS 1.2 as a max version for outgoing connections, but future Envoy releases [may change this to TLS 1.3](https://github.com/envoyproxy/envoy/issues/9300).",
                yaml:
                  "Set the default maximum TLS version supported. Must be greater than or equal to `tls_min_version`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy will default to TLS 1.2 as a max version for outgoing connections, but future Envoy releases [may change this to TLS 1.3](https://github.com/envoyproxy/envoy/issues/9300).",
              },
            },
            {
              name: 'CipherSuites',
              type: 'array<string>: <optional>',
              description: `Set the default list of TLS cipher suites
                            to support when negotiating connections using
                            TLS 1.2 or earlier. If unspecified, Envoy will use a
                            [default server cipher list](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#envoy-v3-api-field-extensions-transport-sockets-tls-v3-tlsparameters-cipher-suites).
                            The list of supported cipher suites can seen in
                            [\`consul/types/tls.go\`](https://github.com/hashicorp/consul/blob/v1.11.2/types/tls.go#L154-L169)
                            and is dependent on underlying support in Envoy. Future
                            releases of Envoy may remove currently-supported but
                            insecure cipher suites, and future releases of Consul
                            may add new supported cipher suites if any are added to
                            Envoy.`,
            },
          ],
        },
      ],
    },
    {
      name: 'HTTP',
      type: 'HTTPConfig: <optional>',
      description: 'HTTP configuration for the service mesh.',
      children: [
        {
          name: 'SanitizeXForwardedClientCert',
          type: 'bool: <optional>',
          description: `If configured to \`true\`, the \`forward_client_cert_details\` option will be set to \`SANITIZE\`
                        for all Envoy proxies. As a result, Consul will not include the \`x-forwarded-client-cert\` header in the next hop.
                        If set to \`false\` (default), the XFCC header is propagated to upstream applications.`,
        },
        {
          name: 'Incoming',
          type: 'DirectionalHTTPConfig: <optional>',
          description: `HTTP configuration for inbound traffic to mesh proxies.`,
          children: [
            {
              name: 'RequestNormalization',
              type: 'RequestNormalizationConfig: <optional>',
              description: `Request normalization configuration for inbound traffic to mesh proxies.`,
              children: [
                {
                  name: 'InsecureDisablePathNormalization',
                  type: 'bool: false',
                  description: `Sets the value of the \`normalize_path\` option in the Envoy listener's \`HttpConnectionManager\`.  The default value is \`false\`.
                                When set to \`true\` in Consul, \`normalize_path\` is set to \`false\` for the Envoy proxy.
                                This parameter disables the normalization of request URL paths according to RFC 3986,
                                conversion of \`\\\` to \`/\`, and decoding non-reserved %-encoded characters. When using L7
                                intentions with path match rules, we recommend enabling path normalization in order
                                to avoid match rule circumvention with non-normalized path values.`,
                },
                {
                  name: 'MergeSlashes',
                  type: 'bool: false',
                  description: `Sets the value of the \`merge_slashes\` option in the Envoy listener's \`HttpConnectionManager\`. The default value is \`false\`.
                                This option controls the normalization of request URL paths by merging consecutive \`/\` characters. This normalization is not part
                                of RFC 3986. When using L7 intentions with path match rules, we recommend enabling this setting to avoid match rule circumvention through non-normalized path values, unless legitimate service
                                traffic depends on allowing for repeat \`/\` characters, or upstream services are configured to
                                differentiate between single and multiple slashes.`,
                },
                {
                  name: 'PathWithEscapedSlashesAction',
                  type: 'string: ""',
                  description: `Sets the value of the \`path_with_escaped_slashes_action\` option in the Envoy listener's
                               \`HttpConnectionManager\`. The default value of this option is empty, which is
                               equivalent to \`IMPLEMENTATION_SPECIFIC_DEFAULT\`. This parameter controls the action taken in response to request URL paths with escaped
                               slashes in the path. When using L7 intentions with path match rules, we recommend enabling this setting to avoid match rule circumvention through non-normalized path values, unless legitimate service
                               traffic depends on allowing for escaped \`/\` or \`\\\` characters, or upstream services are configured to
                               differentiate between escaped and unescaped slashes. Refer to the Envoy documentation for more information on available
                               options.`,
                },
                {
                  name: 'HeadersWithUnderscoresAction',
                  type: 'string: ""',
                  description: `Sets the value of the \`headers_with_underscores_action\` option in the Envoy listener's
                                \`HttpConnectionManager\` under \`common_http_protocol_options\`. The default value of this option is
                                empty, which is equivalent to \`ALLOW\`. Refer to the Envoy documentation for more information on available options.`,
                },
              ],
            },
          ],
        }
      ],
    },
    {
      name: 'Peering',
      type: 'PeeringMeshConfig: <optional>',
      description:
        'Controls configuration specific to [peering connections](/consul/docs/connect/cluster-peering).',
      children: [
        {
          name: 'PeerThroughMeshGateways',
          type: 'bool: <optional>',
          description: `Determines if peering control-plane traffic should be routed through mesh gateways.
                        When enabled, dialing cluster attempt to contact peers through their mesh gateway.
                        Clusters that accept calls advertise the address of their mesh gateways, rather than the address of their Consul servers.`,
        },
      ],
    },
  ]}
/>

## ACLs

Configuration entries may be protected by [ACLs](/consul/docs/security/acl).

Reading a `mesh` config entry requires no specific privileges.

Creating, updating, or deleting a `mesh` config entry requires
`operator:write`.
