V2: reverse-proxy transparent

1. My Caddy version (caddy -version):

v2.0.0-beta9 h1:oILdAOfunJ4ijBN9kOWjFIeH8EufBX/N1pC9HbnwjzU=

2. How I run Caddy:

Please provide all of the relevant information and DO NOT REDACT anything except passwords/keys. Thank you!

a. System environment:

OS, relevant versions, systemd? docker? etc.

CentOS 7 amd64

b. Command:

$ caddy start --config Caddyfile --adapter caddyfile

c. Service/unit/compose file:

Not used

d. My complete Caddyfile:

unknwon.dev {
    reverse_proxy * localhost:4333 {

3. The problem I’m having:

Please describe the issue thoroughly enough so that anyone can reproduce the exact behavior you’re seeing. Be as specific as possible.

In v1, the transparent subdirective would work, but I can’t find anything similar in v2 docs.

4. Error messages and/or full log output:

reload: adapting config using caddyfile: parsing caddyfile tokens for 'reverse_proxy': /etc/caddy/Caddyfile:23 - Error during parsing: unrecognized subdirective transparent

5. What I already tried:

Read through https://github.com/caddyserver/caddy/wiki/v2:-Documentation.

6. Links to relevant resources:

Hi @Unknwon, the error Caddy has output:

This is because there is no transparent preset for v2’s reverse_proxy directive.

For any headers your upstream requires, you will need to add them manually with the header_up subdirective.


For reference, the v1 preset adds the following:

  • transparent
    Passes thru host information from the original request as most backend apps would expect. Shorthand for:
header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {remote}
header_upstream X-Forwarded-Port {server_port}
header_upstream X-Forwarded-Proto {scheme}


The equivalent v2 Caddyfile should be as follows:

header_up Host {http.request.host}
header_up X-Real-IP {http.request.remote}
header_up X-Forwarded-For {http.request.remote}
header_up X-Forwarded-Port {http.request.port}
header_up X-Forwarded-Proto {http.request.scheme}

I don’t believe there is a placeholder for remote IP right now. (edit: Updated!)


The remote IP is basically all I want… :cry:

There might be one as yet undocumented. Once I find it, I’ll edit the post and let you know.

1 Like

@Unknwon, could you try with {http.request.remote} and let me know if that works?

(see: https://github.com/caddyserver/caddy/blob/7ff02f37b6cbdf8e73a47d94604672ca2f1f1aa7/modules/caddyhttp/replacer.go#L82-L83)

SSHing to my server…

It works! Thank you :smiley:

1 Like

Yeah, before we reach 2.0 stable I’ll be sure to go back and add more shorthand placeholders for the Caddyfile. Right now you have to use their full name for some of them.

Somewhat related question: can Caddy reverse proxy to the backend app using HTTP/2, or does it always convert to HTTP/1.1 like Nginx?

I’m asking having read this.

It can use HTTP/2, but HTTP/2 requires HTTPS, so make sure to enable HTTPS to your backends. In your HTTP transport, define at least: "tls": {} (or for the Caddyfile, use the tls subdirective in your HTTP transport.)

1 Like

The examples above did not work for me - I ended up with the below (note the more specific host reference).

header_up Host {http.request.host}
header_up X-Real-IP {http.request.remote.host}
header_up X-Forwarded-For {http.request.remote.host}
header_up X-Forwarded-Port {http.request.port}
header_up X-Forwarded-Proto {http.request.scheme}
1 Like