Back to Apisix

request-id

docs/en/latest/plugins/request-id.md

3.17.034.8 KB
Original Source
<!-- # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # --> <head> <link rel="canonical" href="https://docs.api7.ai/hub/request-id" /> </head>

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

Description

The request-id Plugin assigns a unique ID to each request proxied through the gateway, which can be used for request tracking and debugging. If a request already includes an ID in the header specified by header_name and the value is not empty (""), the plugin uses that value as the request ID. Otherwise, it generates a new one and does not overwrite a valid existing ID.

The request ID is included in gateway logs by default. When the Plugin is enabled, it is also added to the response header.

Attributes

NameTypeRequiredDefaultValid valuesDescription
header_namestringFalse"X-Request-Id"Name of the header that carries the request unique ID. Note that if a request carries an ID in the header_name header, the Plugin will use the header value as the unique ID and will not overwrite it with the generated ID.
include_in_responsebooleanFalsetrueIf true, include the generated request ID in the response header, where the name of the header is the header_name value.
algorithmstringFalse"uuid"["uuid","nanoid","range_id","ksuid"]Algorithm used for generating the unique ID. When set to uuid , the Plugin generates a universally unique identifier. When set to nanoid, the Plugin generates a compact, URL-safe ID. When set to range_id, the Plugin generates a sequential ID with specific parameters. When set to ksuid, the Plugin generates a sequential ID with timestamp and random number.
range_idobjectFalseConfiguration for generating a request ID using the range_id algorithm.
range_id.char_setstringFalse"abcdefghijklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789"minimum length 6Character set used for the range_id algorithm.
range_id.lengthintegerFalse16>=6Length of the generated ID for the range_id algorithm.

Examples

The examples below demonstrate how you can configure request-id in different scenarios.

:::note

You can fetch the admin_key from config.yaml and save to an environment variable with the following command:

bash
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

:::

Understand Request ID in Gateway Logs

The request ID is included in both access and error logs in APISIX from version 3.15.0, regardless of whether the Plugin is enabled.

  • When the Plugin is disabled, the request ID defaults to NGINX's built-in $request_id.
  • When the Plugin is enabled, the request ID is set to the unique ID generated by the Plugin.

This ensures request tracing is always available, with enhanced functionality when the Plugin is enabled.

The following example demonstrates how the request ID appears in the gateway logs when the Plugin is disabled and when it is enabled.

Create a Route without the request-id Plugin:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "request-id-route",
    "uri": "/anything",
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: request-id-service
    routes:
      - name: request-id-route
        uris:
          - /anything
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
yaml
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: httpbin-external-domain
spec:
  type: ExternalName
  externalName: httpbin.org
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: request-id-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
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: request-id-route
spec:
  ingressClassName: apisix
  http:
    - name: request-id-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f request-id-ic.yaml
</TabItem> </Tabs>

Send a request to the Route:

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

You should receive an HTTP/1.1 200 OK response. In the gateway log, you should see an entry similar to the following, where the last value is the request ID from NGINX's built-in $request_id:

text
192.168.215.1 - - [30/Jan/2026:07:21:31 +0000] localhost:9080 "GET /anything HTTP/1.1" 200 391 1.657 "-" "curl/8.6.0" 3.210.41.225:80 200 1.608 "http://localhost:9080" "8a14012e5d0414aff4f15f04b0bd8cb9"

Update the Route with the request-id Plugin:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "request-id-route",
    "uri": "/anything",
    "plugins": {
      "request-id": {}
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: request-id-service
    routes:
      - name: request-id-route
        uris:
          - /anything
        plugins:
          request-id: {}
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
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: request-id-plugin-config
spec:
  plugins:
    - name: request-id
      config:
        _meta:
          disable: false
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: request-id-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: request-id-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
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: request-id-route
spec:
  ingressClassName: apisix
  http:
    - name: request-id-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: request-id
        enable: true
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f request-id-ic.yaml
</TabItem> </Tabs>

Send a request to the Route:

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

You should receive an HTTP/1.1 200 OK response. In the gateway log, you should see an entry similar to the following, where the last value is the request ID generated by the Plugin:

text
192.168.215.1 - - [30/Jan/2026:07:36:24 +0000] localhost:9080 "GET /anything HTTP/1.1" 200 391 0.685 "-" "curl/8.6.0" 52.20.30.6:80 200 0.653 "http://localhost:9080" "8c0ac818-f9d6-4160-be60-8fc74e76be73"

Attach Request ID to Default Response Header

The following example demonstrates how to configure request-id on a Route which attaches a generated request ID to the default X-Request-Id response header, if the header value is not passed in the request. When the X-Request-Id header is set in the request, the Plugin will take the value in the request header as the request ID.

Create a Route with the request-id Plugin using its default configurations (explicitly defined):

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "request-id-route",
    "uri": "/anything",
    "plugins": {
      "request-id": {
        "header_name": "X-Request-Id",
        "include_in_response": true,
        "algorithm": "uuid"
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: request-id-service
    routes:
      - name: request-id-route
        uris:
          - /anything
        plugins:
          request-id:
            header_name: X-Request-Id
            include_in_response: true
            algorithm: uuid
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
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: request-id-plugin-config
spec:
  plugins:
    - name: request-id
      config:
        header_name: X-Request-Id
        include_in_response: true
        algorithm: uuid
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: request-id-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: request-id-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
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: request-id-route
spec:
  ingressClassName: apisix
  http:
    - name: request-id-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: request-id
        enable: true
        config:
          header_name: X-Request-Id
          include_in_response: true
          algorithm: uuid
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f request-id-ic.yaml
</TabItem> </Tabs>

Send a request to the Route:

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

You should receive an HTTP/1.1 200 OK response and see the response includes the X-Request-Id header with a generated ID:

text
X-Request-Id: b9b2c0d4-d058-46fa-bafc-dd91a0ccf441

Send a request to the Route with a empty request ID in the header:

shell
curl -i "http://127.0.0.1:9080/anything" -H 'X-Request-Id;'

You should receive an HTTP/1.1 200 OK response and see the response includes the X-Request-Id header with a generated ID:

text
X-Request-Id: b9b2c0d4-d058-46fa-bafc-dd91a0ccf441

Send a request to the Route with a custom request ID in the header:

shell
curl -i "http://127.0.0.1:9080/anything" -H 'X-Request-Id: some-custom-request-id'

You should receive an HTTP/1.1 200 OK response and see the response includes the X-Request-Id header with the custom request ID:

text
X-Request-Id: some-custom-request-id

Attach Request ID to Custom Response Header

The following example demonstrates how to configure request-id on a Route which attaches a generated request ID to a specified header.

Create a Route with the request-id Plugin to define a custom header that carries the request ID and include the request ID in the response header:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "request-id-route",
    "uri": "/anything",
    "plugins": {
      "request-id": {
        "header_name": "X-Req-Identifier",
        "include_in_response": true
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: request-id-service
    routes:
      - name: request-id-route
        uris:
          - /anything
        plugins:
          request-id:
            header_name: X-Req-Identifier
            include_in_response: true
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
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: request-id-plugin-config
spec:
  plugins:
    - name: request-id
      config:
        header_name: X-Req-Identifier
        include_in_response: true
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: request-id-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: request-id-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
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: request-id-route
spec:
  ingressClassName: apisix
  http:
    - name: request-id-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: request-id
        enable: true
        config:
          header_name: X-Req-Identifier
          include_in_response: true
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f request-id-ic.yaml
</TabItem> </Tabs>

Send a request to the route:

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

You should receive an HTTP/1.1 200 OK response and see the response includes the X-Req-Identifier header with a generated ID:

text
X-Req-Identifier: 1c42ff59-ee4c-4103-a980-8359f4135b21

Hide Request ID in Response Header

The following example demonstrates how to configure request-id on a Route which attaches a generated request ID to a specified header. The header containing the request ID should be forwarded to the Upstream service but not returned in the response header.

Create a Route with the request-id Plugin to define a custom header that carries the request ID and not include the request ID in the response header:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "request-id-route",
    "uri": "/anything",
    "plugins": {
      "request-id": {
        "header_name": "X-Req-Identifier",
        "include_in_response": false
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: request-id-service
    routes:
      - name: request-id-route
        uris:
          - /anything
        plugins:
          request-id:
            header_name: X-Req-Identifier
            include_in_response: false
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
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: request-id-plugin-config
spec:
  plugins:
    - name: request-id
      config:
        header_name: X-Req-Identifier
        include_in_response: false
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: request-id-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: request-id-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
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: request-id-route
spec:
  ingressClassName: apisix
  http:
    - name: request-id-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: request-id
        enable: true
        config:
          header_name: X-Req-Identifier
          include_in_response: false
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f request-id-ic.yaml
</TabItem> </Tabs>

Send a request to the Route:

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

You should receive an HTTP/1.1 200 OK response not and see X-Req-Identifier header among the response headers. In the response body, you should see:

json
{
  "args": {},
  "data": "",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Host": "127.0.0.1",
    "User-Agent": "curl/8.6.0",
    "X-Amzn-Trace-Id": "Root=1-6752748c-7d364f48564508db1e8c9ea8",
    "X-Forwarded-Host": "127.0.0.1",
    "X-Req-Identifier": "268092bc-15e1-4461-b277-bf7775f2856f"
  },
  ...
}

This shows the request ID is forwarded to the Upstream service but not returned in the response header.

Use nanoid Algorithm

The following example demonstrates how to configure request-id on a Route and use the nanoid algorithm to generate the request ID.

Create a Route with the request-id Plugin as such:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "request-id-route",
    "uri": "/anything",
    "plugins": {
      "request-id": {
        "algorithm": "nanoid"
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: request-id-service
    routes:
      - name: request-id-route
        uris:
          - /anything
        plugins:
          request-id:
            algorithm: nanoid
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
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: request-id-plugin-config
spec:
  plugins:
    - name: request-id
      config:
        algorithm: nanoid
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: request-id-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: request-id-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
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: request-id-route
spec:
  ingressClassName: apisix
  http:
    - name: request-id-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: request-id
        enable: true
        config:
          algorithm: nanoid
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f request-id-ic.yaml
</TabItem> </Tabs>

Send a request to the Route:

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

You should receive an HTTP/1.1 200 OK response and see that the response includes the X-Request-Id header with an ID generated using the nanoid algorithm:

text
X-Request-Id: kepgHWCH2ycQ6JknQKrX2

Use ksuid Algorithm

The following example demonstrates how to configure request-id on a Route and use the ksuid algorithm to generate the request ID.

Create a Route with the request-id Plugin as such:

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">
shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "request-id-route",
    "uri": "/anything",
    "plugins": {
      "request-id": {
        "algorithm": "ksuid"
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">
yaml
services:
  - name: request-id-service
    routes:
      - name: request-id-route
        uris:
          - /anything
        plugins:
          request-id:
            algorithm: ksuid
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">
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: request-id-plugin-config
spec:
  plugins:
    - name: request-id
      config:
        algorithm: ksuid
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: request-id-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: request-id-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80
</TabItem> <TabItem value="apisix-crd">
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: request-id-route
spec:
  ingressClassName: apisix
  http:
    - name: request-id-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: request-id
        enable: true
        config:
          algorithm: ksuid
</TabItem> </Tabs>

Apply the configuration to your cluster:

shell
kubectl apply -f request-id-ic.yaml
</TabItem> </Tabs>

Send a request to the Route:

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

You should receive an HTTP/1.1 200 OK response and see the response includes the X-Request-Id header with an ID generated using the ksuid algorithm:

text
X-Request-Id: 325ghCANEKjw6Jsfejg5p6QrLYB

If the ksuid is installed, this ID can be viewed through ksuid -f inspect 325ghCANEKjw6Jsfejg5p6QrLYB:

text
REPRESENTATION:

    String: 325ghCANEKjw6Jsfejg5p6QrLYB
    Raw: 15430DBBD7F68AD7CA0AE277772AB36DDB1A3C13

COMPONENTS:

    Time: 2025-09-01 16:39:23 +0800 CST
    Timestamp: 356715963
    Payload: D7F68AD7CA0AE277772AB36DDB1A3C13

Attach Request ID Globally and on a Route

The following example demonstrates how to configure request-id as a global Plugin and on a Route to attach two IDs.

<Tabs groupId="api" defaultValue="admin-api" values={[ {label: 'Admin API', value: 'admin-api'}, {label: 'ADC', value: 'adc'}, {label: 'Ingress Controller', value: 'aic'} ]}>

<TabItem value="admin-api">

Create a global rule for the request-id Plugin which adds request ID to a custom header:

shell
curl -i "http://127.0.0.1:9180/apisix/admin/global_rules" -X PUT -d '{
  "id": "rule-for-request-id",
  "plugins": {
    "request-id": {
      "header_name": "Global-Request-ID"
    }
  }
}'

Create a Route with the request-id Plugin which adds request ID to a different custom header:

shell
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
  -H "X-API-KEY: ${admin_key}" \
  -d '{
    "id": "request-id-route",
    "uri": "/anything",
    "plugins": {
      "request-id": {
        "header_name": "Route-Request-ID"
      }
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "httpbin.org:80": 1
      }
    }
  }'
</TabItem> <TabItem value="adc">

Configure the request-id plugin as a global rule and on a route:

yaml
global_rules:
  - id: rule-for-request-id
    plugins:
      request-id:
        header_name: Global-Request-ID
services:
  - name: request-id-service
    routes:
      - name: request-id-route
        uris:
          - /anything
        plugins:
          request-id:
            header_name: Route-Request-ID
    upstream:
      type: roundrobin
      nodes:
        - host: httpbin.org
          port: 80
          weight: 1

Synchronize the configuration to the gateway:

shell
adc sync -f adc.yaml
</TabItem> <TabItem value="aic">

<Tabs groupId="k8s-api" defaultValue="gateway-api" values={[ {label: 'Gateway API', value: 'gateway-api'}, {label: 'APISIX CRD', value: 'apisix-crd'} ]}>

<TabItem value="gateway-api">

Update your GatewayProxy manifest to enable request-id as a global plugin:

yaml
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
  namespace: aic
  name: apisix-config
spec:
  provider:
    type: ControlPlane
    controlPlane:
      # ...
      # your control plane connection configuration
  plugins:
  - name: request-id
    enabled: true
    config:
      header_name: Global-Request-ID

Create a route with the request-id plugin which adds request ID to a different custom header:

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: request-id-plugin-config
spec:
  plugins:
    - name: request-id
      config:
        header_name: Route-Request-ID
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  namespace: aic
  name: request-id-route
spec:
  parentRefs:
    - name: apisix
  rules:
    - matches:
        - path:
            type: Exact
            value: /anything
      filters:
        - type: ExtensionRef
          extensionRef:
            group: apisix.apache.org
            kind: PluginConfig
            name: request-id-plugin-config
      backendRefs:
        - name: httpbin-external-domain
          port: 80

Apply the configuration to your cluster:

shell
kubectl apply -f gatewayproxy.yaml -f request-id-ic.yaml
</TabItem> <TabItem value="apisix-crd">

Create a Kubernetes manifest file for a global request-id plugin:

yaml
apiVersion: apisix.apache.org/v2
kind: ApisixGlobalRule
metadata:
  namespace: aic
  name: global-request-id
spec:
  ingressClassName: apisix
  plugins:
  - name: request-id
    enable: true
    config:
      header_name: Global-Request-ID

Create a route with the request-id plugin which adds request ID to a different custom header:

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: request-id-route
spec:
  ingressClassName: apisix
  http:
    - name: request-id-route
      match:
        paths:
          - /anything
      upstreams:
      - name: httpbin-external-domain
      plugins:
      - name: request-id
        enable: true
        config:
          header_name: Route-Request-ID

Apply the configuration to your cluster:

shell
kubectl apply -f global-request-id.yaml -f request-id-ic.yaml
</TabItem> </Tabs> </TabItem> </Tabs>

Send a request to the Route:

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

You should receive an HTTP/1.1 200 OK response and see the response includes the following headers:

text
Global-Request-ID: 2e9b99c1-08ed-4a74-b347-49c0891b07ad
Route-Request-ID: d755666b-732c-4f0e-a30e-a7a71ace4e26