# client-control

The `client-control` plugin sets a request body size limit on a route or service. It lets individual APIs enforce a limit that differs from the gateway-wide NGINX configuration and rejects oversized requests before they reach the upstream service.

## Request Handling and Product Compatibility[​](#request-handling-and-product-compatibility "Direct link to Request Handling and Product Compatibility")

When a request declares `Content-Length`, the plugin rejects it immediately with `413 Request Entity Too Large` if the declared size exceeds a nonzero configured limit. For a request without a known length, the gateway continues enforcing the limit while NGINX reads the body.

The plugin is available in APISIX and API7 Enterprise. Its behavior for gRPC upstreams differs in the currently maintained versions:

| Product                            | HTTP requests                  | Requests to gRPC upstreams                                                                                                                                                                 |
| ---------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| APISIX 3.19.0                      | Enforces the configured limit. | Performs the initial declared-length check but does not reapply the runtime limit after the internal redirect. Do not rely on this plugin as the gRPC body-size control in this version.   |
| APISIX 3.20.0                      | Enforces the configured limit. | Reapplies the limit after the internal gRPC redirect, including when the request does not declare `Content-Length`.                                                                        |
| API7 Enterprise 3.9.23 and 3.10.10 | Enforces the configured limit. | Performs the initial declared-length check but does not reapply the runtime limit after the internal redirect. Do not rely on this plugin as the gRPC body-size control in these versions. |

## Example[​](#example "Direct link to Example")

Set a 1 KiB limit on a route, then send requests below and above the limit to verify that the gateway rejects oversized bodies.

### Limit Request Body Size[​](#limit-request-body-size "Direct link to Limit Request Body Size")

Create a route with the `client-control` plugin:

* Admin API
* ADC
* Ingress Controller

```
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \

  -H "X-API-KEY: ${ADMIN_API_KEY}" \

  -d '{

    "id": "client-control-route",

    "uri": "/anything",

    "plugins": {

      "client-control": {

        "max_body_size": 1024

      }

    },

    "upstream": {

      "type": "roundrobin",

      "nodes": {

        "httpbin.org:80": 1

      }

    }

  }'
```

adc.yaml

```
services:

  - name: client-control-service

    labels:

      docs-example: client-control

    routes:

      - name: client-control-route

        uris:

          - /anything

        plugins:

          client-control:

            max_body_size: 1024

    upstream:

      type: roundrobin

      nodes:

        - host: httpbin.org

          port: 80

          weight: 1
```

Preview the changes and confirm that they only affect resources for this guide:

```
adc diff -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=client-control
```

Synchronize the configuration to the gateway:

```
adc sync -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=client-control
```

* Gateway API
* APISIX CRD

client-control-ic.yaml

```
apiVersion: v1

kind: Service

metadata:

  namespace: aic

  name: httpbin-external-domain

spec:

  type: ExternalName

  externalName: httpbin.org

---

apiVersion: apisix.apache.org/v1alpha1

kind: PluginConfig

metadata:

  namespace: aic

  name: client-control-plugin-config

spec:

  plugins:

    - name: client-control

      config:

        max_body_size: 1024

---

apiVersion: gateway.networking.k8s.io/v1

kind: HTTPRoute

metadata:

  namespace: aic

  name: client-control-route

spec:

  parentRefs:

    - name: apisix

  rules:

    - matches:

        - path:

            type: Exact

            value: /anything

      filters:

        - type: ExtensionRef

          extensionRef:

            group: apisix.apache.org

            kind: PluginConfig

            name: client-control-plugin-config

      backendRefs:

        - name: httpbin-external-domain

          port: 80
```

client-control-ic.yaml

```
apiVersion: apisix.apache.org/v2

kind: ApisixUpstream

metadata:

  namespace: aic

  name: httpbin-external-domain

spec:

  ingressClassName: apisix

  externalNodes:

    - type: Domain

      name: httpbin.org

---

apiVersion: apisix.apache.org/v2

kind: ApisixRoute

metadata:

  namespace: aic

  name: client-control-route

spec:

  ingressClassName: apisix

  http:

    - name: client-control-route

      match:

        paths:

          - /anything

      upstreams:

        - name: httpbin-external-domain

      plugins:

        - name: client-control

          enable: true

          config:

            max_body_size: 1024
```

Apply the configuration to the cluster:

```
kubectl apply -f client-control-ic.yaml
```

Send a small request that stays within the limit:

```
curl -i "http://127.0.0.1:9080/anything" \

  -H "Content-Type: application/json" \

  -d '{"message":"ok"}'
```

The request should reach the upstream and return an HTTP 2xx response.

Send a 2 KiB request body:

```
head -c 2048 /dev/zero | \

  curl -i "http://127.0.0.1:9080/anything" \

    -H "Content-Type: application/octet-stream" \

    --data-binary @-
```

The gateway should reject the request with `413 Request Entity Too Large`.
