goauthentik / goauthentik/authentik

Proxy outpost (Rust, 2026.8.x) sends duplicate Host header on Proxy Provider requests to Internal Host — nginx rejects with 400 (distinct from #25226 / not fixed by #25234)

Open
#25,643 0 comments 1 reaction 2 assignees Claimed by @rissson View on GitHub
bug/confirmed
Dominant language
Python
Stars
25.6k
Forks
2k
Avg merge
1d 1h
Merged PRs (30d)
644

Description

### Describe the bug

After upgrading to 2026.8.0 (Rust proxy outpost), every authenticated request to an app behind a Proxy Provider fails with a 400 Bad Request from the backend's nginx. This reproduces for every user, 100% of the time — login/auth with the upstream IdP succeeds, but the proxied request to the application itself fails immediately after.

This looks related to #25226 (fixed by #25234) but is a different code path: that issue was about the token-introspection/backchannel request duplicating the same Host value; this is the outpost's request to the Proxy Provider's configured Internal Host, and the duplicated values are two different hosts.

nginx access log shows the same fingerprint as #25226 — empty request line, bare 400:

`172.17.2.3 - - [01/Sep/2026:16:34:07 +0100] "-" 400 157 "-" "-" "-"`

With debug logging enabled on the backend's nginx, the actual cause:
`
client sent duplicate host header: "host: 192.168.0.4:9443", previous value: "host: 192.168.0.4:8971" while reading client request headers, client: 172.17.2.3, server: , host: "192.168.0.4:8971"`

192.168.0.4:9443 is the outpost's own bind port — not a value sent by anything upstream of the outpost (confirmed via the reverse proxy config in front of authentik, which preserves the original client Host header and does not override it). 192.168.0.4:8971 is the correct Internal Host configured on the Proxy Provider. The outpost appears to insert its own listener host:port as a Host header before separately setting the correct one for internal_host, without clearing the first — the same defect class as #25226, in a different request-construction path.

Confirmed via packet capture that TLS negotiation between the outpost and the internal host completes cleanly (full TLS 1.3 handshake, valid encrypted application data exchanged both directions) — ruling out any TLS/network cause; this is purely a malformed outgoing HTTP request from the outpost.

Still present on 2026.8.1 (retested after upgrading specifically to check whether #25234 resolved it — it did not).

### How to reproduce

1. Proxy Provider (not forward-auth) protecting an app, Internal Host set to https://:, Internal Host SSL Validation disabled.
2. A reverse proxy (Caddy, in our case) in front of authentik's outpost, preserving the client Host header.
3. Log in as any user through the upstream IdP; authentik authenticates successfully.
4. On redirect to the protected app, the backend returns 400.

### Expected behavior

The outpost sends exactly one Host header — matching Internal Host — on requests it proxies to the configured backend application.

Deployment Method: Docker (embedded outpost)

Version: 2026.8.1 (also present on 2026.8.0)

Relevant log output

```
client sent duplicate host header: "host: 192.168.0.4:9443", previous value: "host: 192.168.0.4:8971" while reading client request headers, client: 172.17.2.3, server: , host: "192.168.0.4:8971"
172.17.2.3 - - [01/Sep/2026:16:34:07 +0100] "-" 400 157 "-" "-" "-" request_time="0.000" upstream_response_time="-"
```

### Screenshots

_No response_

### Additional context

Related to #25226 / #25234, but that fix targeted the token-backchannel request specifically and does not cover this path. Happy to provide full pcap, nginx debug logs, and reverse-proxy config on request.

### Deployment Method

Docker

### Version

2026.8.1

### Relevant log output

```shell

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.