A Traefik middleware plugin that injects an X-Request-ID header with a generated UUIDv4 value into HTTP requests and responses, allowing downstream services to correlate and trace individual requests.
Based on github.com/mdklapwijk/traefik-plugin-request-id.
X-Request-ID checks incoming requests for the configured header (default X-Request-ID). If the header is absent, the plugin generates a new UUIDv4 value and adds it to both the request (so backends can read it) and the response (so clients and proxies can correlate it). If the header is already present, the plugin passes the request through without modification.
The plugin can be disabled at runtime via configuration, and the header name is fully configurable.
# traefik.yml
experimental:
plugins:
requestid:
moduleName: github.com/docplanner/requestid
version: v0.1.0# dynamic.yaml
http:
middlewares:
requestid:
plugin:
requestid:
headerName: "X-Request-ID"
enabled: true
routers:
my-router:
rule: "PathPrefix(`/`)"
service: my-service
middlewares:
- requestidapiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: requestid
namespace: traefik-system
spec:
plugin:
requestid:
headerName: "X-Request-ID"
enabled: true| Field | Type | Required | Default | Description |
|---|---|---|---|---|
headerName |
string |
No | X-Request-ID |
Name of the header to inject |
enabled |
bool |
No | true |
Whether the plugin is active |
- If the configured header is absent from the request, a new UUIDv4 is generated and added to both the request and the response.
- If the configured header is already present, the request passes through unchanged.
- When
enabledisfalse, the plugin is a no-op and all requests pass through unmodified. - UUIDs are generated using Go's
github.com/google/uuidpackage (version 4, random).
Clone the repository and use the provided Makefile:
make test # run unit tests with coverage
make lint # run golangci-lint (requires golangci-lint installed)A ready-to-use local development setup is included in the docker/ directory. It loads the plugin from the repo root using Traefik's local plugin mode.
docker/
├── docker-compose.yml # Traefik + whoami backend
└── traefik-config/
├── traefik.yaml # Traefik static config (local plugin registration)
└── dynamic.yaml # Dynamic config (middleware rules + routing)
Start the stack:
cd docker
docker compose upTest the plugin:
# Request without X-Request-ID: plugin generates one
curl -sv http://localhost:8888/ 2>&1 | grep -i x-request-id
# Request with existing X-Request-ID: plugin preserves it
curl -sv -H "X-Request-ID: my-custom-id" http://localhost:8888/ 2>&1 | grep -i x-request-idThe Traefik dashboard is available at http://localhost:9090.
Edit docker/traefik-config/dynamic.yaml to change middleware settings. Edit requestid.go at the repo root to change plugin logic, then restart the stack with docker compose restart traefik.
To make the plugin available in the Traefik Plugins Catalog:
- Ensure the GitHub repository is public.
- Add the
traefik-plugintopic to the repository. - Verify
.traefik.ymlexists at the repo root with validtestData. - Verify
go.modexists at the repo root. - Create a git tag (e.g.
v0.1.0). - The catalog polls GitHub daily and will pick up the plugin automatically.
This plugin is a refactored version of traefik-plugin-request-id by @mdklapwijk, which was itself based on: