Am evaluating Traefik for a gateway api controller, its mostly working fine till now except this specific scenario...
An HTTPRoute with a path match in combination with a header match does not work IF the header being matched is Host
, it works fine for other headers like authority
or User-Agent
etc.
The exact same HTTPRoute definition works perfectly fine when switched to use the nginx gateway fabric so its not a Gateway API spec issue it seems.
HTTPRoute definition
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: infra-test
namespace: foobar
spec:
parentRefs:
- name: traefik-gateway
namespace: foobar
rules:
- matches:
- path:
type: PathPrefix
value: /
headers:
- name: "host"
type: Exact
value: "FOOBAR_TEST"
backendRefs:
- name: infratest-service
port: 9898
Request to Traefik gateway via an AWS NLB
$ curl -sD - -H "Host: FOOBAR_TEST" http://k8s-obfuscated-95deb4669.elb.us-east-2.amazonaws.com/
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Thu, 23 Jan 2025 13:30:07 GMT
Content-Length: 19
404 page not found
Works with useragent
$ curl -sD - -H "User-agent: FOOBAR_TEST" http://k8s-obfuscated-95deb4669.elb.us-east-2.amazonaws.com/
HTTP/1.1 200 OK
Content-Length: 402
Content-Type: application/json; charset=utf-8
Date: Thu, 23 Jan 2025 13:29:33 GMT
X-Content-Type-Options: nosniff
{
"hostname": "infratest-service-6dd866b6f6-5lx4v",
"version": "6.7.1",
"revision": "6b7aab8a10d6ee8b895b0a5048f4ab0966ed29ff",
"color": "#34577c",
"logo": "https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif",
"message": "greetings from podinfo v6.7.1",
"goos": "linux",
"goarch": "arm64",
"runtime": "go1.23.2",
"num_goroutine": "6",
"num_cpu": "8"
}
Same request with host header match via the nginx gateway NLB
$ curl -sD - -H "Host: FOOBAR_TEST" http://obfuscated-1433974312.us-east-2.elb.amazonaws.com/
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 23 Jan 2025 13:30:56 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 402
Connection: keep-alive
X-Content-Type-Options: nosniff
{
"hostname": "infratest-service-6dd866b6f6-5lx4v",
"version": "6.7.1",
"revision": "6b7aab8a10d6ee8b895b0a5048f4ab0966ed29ff",
"color": "#34577c",
"logo": "https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif",
"message": "greetings from podinfo v6.7.1",
"goos": "linux",
"goarch": "arm64",
"runtime": "go1.23.2",
"num_goroutine": "6",
"num_cpu": "8"
}
I've tried reviewing the code at traefik/pkg/provider/kubernetes/gateway/httproute.go at 2b6a04bc1d7f6c6429fd8c8b0125572dbb2f49c1 · traefik/traefik · GitHub but nothing obvious pops up which maybe removing the host header.
Any pointers around is this supposed to work or am I doing something wrong?
The reason for not using a hostname match under spec is because there is a use case for matching certain paths for any incoming host header but only match /
if the host header also matches.