Automatic HTTPS removes certificate plumbing, not DNS work
Caddy's best feature is easy to explain: give it a public hostname and a handler, and it can obtain a certificate, redirect HTTP to HTTPS, serve modern protocols, renew the certificate, and keep the site running through routine renewal work. A basic reverse proxy can fit in a few Caddyfile lines. That is a meaningful reduction in configuration for personal servers and small production services.
The automation still has prerequisites. Public DNS must point to the server, the relevant ACME challenge must reach it, and Caddy needs persistent writable storage for account and certificate material. Low ports such as 80 and 443 may require capabilities or a privileged listener arrangement. If a firewall, load balancer, or container mapping blocks the challenge, automatic HTTPS has no way to repair the surrounding network.
The Caddyfile stays readable until JSON is the better interface
The Caddyfile is an adapter rather than Caddy's native configuration format. It is pleasant for common static sites, reverse proxies, redirects, headers, and encoders. Caddy converts it into JSON, which maps more directly to loaded modules and routes. Operators can inspect the adapted output before deployment instead of guessing how shorthand expands.
Larger installations may prefer the JSON API because it can change a running configuration without restarting the process. That power creates another security boundary: an exposed admin endpoint can alter the server. Keep it on a protected interface, authenticate any remote control layer, and store the intended configuration in version control. A live API is useful only when the team can also reproduce and audit its state.
What happened when we ran it
Our sandbox installed 553 Go packages in 86 seconds. The build then succeeded in 114 seconds on commit 0cf03d3, using an unprivileged Debian container with 3 CPUs and 8 GB of RAM. The source checkout contained 655 files, about 105,022 lines, and occupied 4.3 MB. Nine CI workflow files were present, while the scanner found no Dockerfile or top-level tests directory.
The Go test run failed with exit code 1 after 78 seconds. It reported 21 package results as passed and 1 as failed out of 22. The supplied final lines show successful results for caddypki, caddytls, filestorage, internal networking, logging, and metrics before the overall FAIL. They do not show the failing package or its error, so we cannot assign a cause from this evidence.
A successful 114-second compile proves that the checked-out source could produce a binary in our environment. The failed suite prevents a clean contributor result. Before distributing a custom build, rerun the suite with full logs, isolate the failing package, and record the exact Go environment. Users installing the official v2.11.4 binary are taking a different path from our source checkout.
Plugins become part of your binary
Caddy's module system covers handlers, storage, authentication, DNS providers, and configuration adapters. The supported custom-build workflow uses xcaddy: it creates a Go module, pins a Caddy version if requested, imports selected plugins, and compiles a new executable. This produces a clean deployment unit with no runtime plugin directory. It also makes the operator responsible for that exact dependency set.
Every plugin changes the artifact you patch and test. A stock release update does not automatically rebuild a private combination, and a module can carry its own configuration or maintenance risks. Keep the xcaddy inputs pinned, generate a repeatable binary, retain its version metadata, and run configuration plus request tests against the result. If standard Caddy covers the job, the official binary is the simpler choice.
HTTP/3 and strict upstreams need a representative test
Caddy supports HTTP/1.1, HTTP/2, and HTTP/3 by default, which is useful when clients and upstreams vary. Protocol translation also creates unusual corners. Open issue 7835 reports that a bodyless HTTP/3 request proxied to a strict HTTP/2 upstream can arrive with an indeterminate content length and receive a 502. The reporter reproduced it on v2.11.4 and listed forcing HTTP/1.1 upstream or disabling HTTP/3 as workarounds.
That issue should not scare a normal HTTP/1.1 backend deployment away. It should change the acceptance test for IIS or another strict HTTP/2 upstream. Send real browser traffic over each enabled client protocol, verify headers and bodies at the backend, and test failure responses. Open issue 7225 likewise reports proxy-placeholder trouble in a particular HTTP proxy path. These are narrow, citable reasons to test the topology you will actually run.
June security fixes make current patching important
GitHub showed 75,237 stars and 266 combined issues and pull requests when fetched. The last source push was August 25, 2026. Release v2.11.4 arrived on June 3 with fixes for Windows backslashes in path matching, query placeholder re-expansion, malformed HTML stripping, header-name collisions, TLS state races, and reverse-proxy request handling. The notes warn that some security fixes can break configurations that depended on earlier behavior.
That is healthy maintenance and a reminder to stage upgrades. Validate the Caddyfile or JSON, exercise certificate issuance in a safe environment, and send representative proxy requests before replacing the production binary. Caddy earns its place by making the common secure path short. It does not excuse careless admin-API exposure, untracked plugin builds, missing state volumes, or skipped regression tests.

