Empty response on http, https does work

1. Caddy version (2.4.3):

2. How I run Caddy:

It is builded in a dockerfile from caddy build-alpine image

a. System environment:

Alpine linux, Docker

d. My complete Caddyfile or JSON config:

    # Debug
    # HTTP/3 support
    servers {
        protocol {
    auto_https disable_redirects



# Matches requests for HTML documents, for static files and for Next.js files,
# except for known API paths and paths with extensions handled by API Platform
@pwa expression `(
        && !{path}.matches("(?i)(?:^/docs|^/graphql|^/bundles/|^/_profiler|^/_wdt|\\.(?:json|html$|csv$|ya?ml$|xml$))")
    || {path} == "/favicon.ico"
    || {path} == "/manifest.json"
    || {path} == "/robots.txt"
    || {path}.startsWith("/_next")
    || {path}.startsWith("/sitemap")`

route {
    root * /srv/api/public

    # Add links to the API docs and to the Mercure Hub if not set explicitly (e.g. the PWA)
    #header ?Link `</docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation", </.well-known/mercure>; rel="mercure"`
    # Disable Google FLOC tracking if not enabled explicitly: https://plausible.io/blog/google-floc
    header ?Permissions-Policy "interest-cohort=()"

    # Comment the following line if you don't want Next.js to catch requests for HTML documents.
    # In this case, they will be handled by the PHP app.
    reverse_proxy @pwa http://{$PWA_UPSTREAM}

    php_fastcgi unix//var/run/php/php-fpm.sock
    encode zstd gzip

3. The problem I’m having:

I disabled the auto_https redirect but when i try to access my application directly on http i only get an empty response 200. If i access the same url on https, it works like a charm.

4. Error messages and/or full log output:

Http request example
{“level”:“info”,“ts”:1626855151.9384563,“logger”:“http.log.access”,“msg”:“handled request”,“request”:{“remote_addr”:“”,“proto”:“HTTP/1.1”,“method”:“GET”,“host”:“localhost”,“uri”:"/",“headers”:{“Sec-Ch-Ua-Mobile”:["?0"],“Upgrade-Insecure-Requests”:[“1”],“Accept”:[“text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9”],“Sec-Fetch-Mode”:[“navigate”],“Accept-Language”:[“de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7,fr;q=0.6”],“Sec-Ch-Ua”:["" Not;A Brand";v=“99”, “Google Chrome”;v=“91”, “Chromium”;v=“91"”],“User-Agent”:[“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36”],“Accept-Encoding”:[“gzip, deflate, br”],“Sec-Fetch-Site”:[“none”],“Sec-Fetch-Dest”:[“document”],“Connection”:[“keep-alive”],“Cache-Control”:[“max-age=0”],“Sec-Fetch-User”:["?1"]}},“common_log”:“ - - [21/Jul/2021:08:12:31 +0000] “GET / HTTP/1.1” 0 0”,“duration”:0.0001057,“size”:0,“status”:0,“resp_headers”:{“Server”:[“Caddy”]}}

5. What I already tried:

Disable all options i could think of, set https to off.

6. Links to relevant resources:

Link to the cloned repository with the caddy config template (under api/docker/caddy) and the used dockerfile (api/Dockerfile) → GitHub - api-platform/api-platform: Create REST and GraphQL APIs, scaffold Jamstack webapps, stream changes in real-time.

Howdy @WhiteRabbitDE, welcome to the Caddy community.

What is {$SERVER_NAME}? The specifics of the site label have major implications for the behaviour of the web server.

What is the desired behaviour, exactly?

Hello @Whitestrake, thanks for the warm welcome :slight_smile:

SERVER_NAME is passed via docker-compose, in this example it is

SERVER_NAME: ${SERVER_NAME:-localhost, caddy:80}

which results in “localhost, caddy:80” since im not setting a value explicitly for my local test here. On my remote docker machine it is something like “container.my.domain.de , caddy:80”

If you mean what i expect with “desired behaviour”: i want to have the same response from my application (PWA or my API) with http and https. Right now, http only returns an empty response.

Your log shows a 200 OK response for a HTTP request on port 80 for an unconfigured site label (“host”:“localhost”).

This is expected behaviour. A request for host caddy should produce the actual configured site behaviour.

I can demonstrate the expected behaviour of your configuration a little bit:

➜ caddy version
v2.4.3 h1:Y1FaV2N4WO3rBqxSYA8UZsZTQdN+PwcoOcAiZTM8C0I=

➜ cat Caddyfile
  auto_https disable_redirects

example.com, localhost:80 {
  respond "Foo bar"


➜ curl -iL --resolve example.com:80: --resolve example.com:443: https://example.com
HTTP/2 200
server: Caddy
content-length: 7
date: Wed, 21 Jul 2021 11:17:23 GMT

Foo bar⏎

➜ curl -iL --resolve example.com:80: --resolve example.com:443: example.com
HTTP/1.1 200 OK
Server: Caddy
Date: Wed, 21 Jul 2021 11:17:27 GMT
Content-Length: 0

➜ curl -iL --resolve example.com:80: --resolve example.com:443: localhost
HTTP/1.1 200 OK
Server: Caddy
Date: Wed, 21 Jul 2021 11:17:31 GMT
Content-Length: 7

Foo bar⏎

https://example.com shows the configured site, and there is no HTTP redirecting (disabled by global option), so a request to http://example.com gets an unconfigured response (200 OK). A request to http://localhost produces the configured site.

This is simple: be unambiguous in your site labeling, e.g.:

http://example.com, https://example.com {
  # ...

There is then no need to disable automatic HTTP redirects at all via the global option (these are only automated when you haven’t already specified a configuration for HTTP).


Wow… it works ! :slight_smile: Thanks a lot @Whitestrake ! And a big thank you for the very detailed explaination !

Have a great day buddy !

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.