Skip to content

chore(deps): update dependency caddy to v2.11.9 - #105

Merged
renovate[bot] merged 1 commit into
mainfrom
renovate/caddy-2.x
Nov 9, 2026
Merged

renovate[bot] merged 1 commit into
mainfrom
renovate/caddy-2.x

Conversation

@renovate

@renovate renovate Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Type Update Change
caddy tools patch 2.11.7 → 2.11.9

Release Notes

caddyserver/caddy (caddy)

v2.11.9

Compare Source

This is a quick follow-up on top of 2.11.8, to fix a regression it introduced and a few more security issues, mostly in FastCGI. It contains only fixes backported from master, plus a couple of small additions. If you're on 2.11.8 and serve PHP, we recommend upgrading.

Huge thank you to our sponsors for keeping the project alive with resources, and for our maintainers who triage and assist tirelessly in this relentless new age of AI.

Highlights

  • Fixed: PHP directory indexes (regression in 2.11.8). A request for a directory with a trailing slash, like /wp-admin/, was matched by the directory itself instead of its index.php, so it never reached PHP and usually got a 404. This broke WordPress admin pages and other apps that serve an index through a trailing-slash URL. A try_files pattern now only matches a directory when it ends in /. Thanks @​dunglas! (#​8352)
  • Path matchers with placeholders now work as expected: placeholders like {env.FOO} are no longer lower-cased into {env.foo} before they're looked up, and their values are compared case-insensitively against the request path, like static patterns. Thanks @​BenMacha! (#​8343)
  • New plain_time_format option for file_server browse: sets the time layout of plain-text directory listings (Accept: text/plain). Thanks @​steffenbusch! (#​8084)
  • Fewer allocations in path cleaning, header rewriting and weighted_round_robin selection. Thanks @​jvoisin! (#​7842)
  • For plugin authors: new httpcaddyfile.Helper.IsNamedRoute() tells a directive whether it's being parsed inside a named route. (#​8354)

⚠️ Breaking changes

  • Conflicting client_auth is now a Caddyfile error. When two site blocks share TLS connection policies for the same hostname but set different client_auth, the adapter used to keep the first one and silently drop the other, which could quietly remove a stricter mTLS requirement. (#​8306)
  • FastCGI requests that are ambiguous about which script they run get 400:
    • when the escaped path (which %-containing path matchers see) and the decoded path would select different scripts, e.g. /public/tool.php%2f..%2f..%2fadmin%2ftool.php (#​8357)
    • on Windows, script paths with an 8.3 short name component (like ADMINI~1) or a : (NTFS alternate data streams) (#​8356)
  • FastCGI env values now take precedence over request headers, so a client can no longer override HTTP_* variables you set with env (see below). (#​8358)

Security fixes

Thank you to everyone who reported responsibly and helped with patches:

  • fastcgi: A client could override any HTTP_* variable set with the FastCGI transport's (or php_fastcgi's) env subdirective by sending a matching request header, for example choosing the user an application sees in HTTP_X_AUTH_USER. Configured values now win. Reported by @​JebeenLee and @​Camel4, fixed by @​dunglas. (GHSA-q34h-28rj-5hjm, #​8358)
  • fastcgi: On Windows, NTFS 8.3 short names and alternate data streams could run a script that a path rule was meant to deny, completing the FastCGI fix from 2.11.8. Thanks @​dunglas. (GHSA-9cr8-wmhh-39pm, #​8356)
  • fastcgi: Encoded slashes and dot segments could make a %-containing path matcher approve one script while another one runs. Thanks @​dunglas. (#​8357)
  • fastcgi: Over HTTP/2, a host field sent next to :authority could make the application see a different host (HTTP_HOST) than the one Caddy routed the request to. Thanks @​dunglas. (#​8355)
  • httpcaddyfile: A stricter client_auth could be silently dropped when merging TLS connection policies (see above). Thanks @​sam-kota. (#​8306)
  • Updated go-jose to v4.1.6 for GHSA-mgcc-cww5-fp2q. (#​8299)

⚠️ These security patches may be breaking if your application relies on the buggy behaviors.

🚨 Notice for Caddy plugin maintainers: Dependabot will probably alert you to the security fixes in Caddy and urge you to upgrade it in your go.mod file. Please ONLY upgrade the Caddy dependency if there's a change to an exported API your plugin uses.

What's Changed

Full Changelog: caddyserver/caddy@v2.11.8...v2.11.9

v2.11.8

Compare Source

This patch release is a big batch of bug fixes and security hardening, plus a handful of small additions. This release is cut from our 2.11 maintenance branch: fixes are backported from master. We recommend upgrading, especially if you serve PHP or use {host} in file paths.

Huge thank you to our sponsors for keeping the project alive with resources, and for our maintainers who triage and assist tirelessly in this relentless new age of AI.

⚠️ Please read the breaking changes below before upgrading. Most of them reject configs or requests that never did what they looked like they did, so most setups won't notice.

Highlights

  • Idle timeouts, round two. More fixes for the idle read/write timeouts introduced in 2.11.6:
    • Per-route timeouts now take precedence over the server-wide read_body_idle / write_idle, and nested timeouts use the innermost one. (#​8121)
    • Over HTTP/2, a handler that paused reading the request body (like reverse_proxy uploading to a slow upstream) no longer loses the body and fails with 502. (#​8125)
    • Deadlines set by handlers now act as a ceiling instead of being overridden, so things like Mercure's dispatch_timeout and FrankenPHP's request_body_timeout work again. Thanks @​dunglas! (#​8145, #​8284)
    • HTTP/1.1 uploads that time out with a little body left no longer hang instead of sending the error response. Thanks @​SiyXo511! (#​8178)
  • Binding privileged ports with fewer capabilities (Linux): If CAP_NET_BIND_SERVICE is permitted but not effective, Caddy raises it just for binding a privileged port. Packagers can use setcap cap_net_bind_service=+p instead of +ep, so Caddy still starts under --cap-drop ALL, OpenShift's restricted-v2, or systemd units with an empty CapabilityBoundingSet=. It also follows the kernel's ip_unprivileged_port_start instead of assuming 1024. (#​8102, #​8253)
  • Small additions:
  • Reverse proxy:
    • headers you set yourself (like Strict-Transport-Security via header) are no longer lost when the upstream sends a 1xx response first, like 103 Early Hints (#​8169)
    • request trailer values are forwarded, not just their names. Thanks @​krishsinghhura! (#​8246)
    • request-only expressions in lb_retry_match no longer retry successful responses (a regression since 2.11.3) (#​8168)
    • dial errors through a forward proxy and to FastCGI backends are retried like other dial errors. Thanks @​adarshxsh and @​zemamba! (#​8264, #​8172)
    • weighted_round_robin no longer panics with fewer weights than upstreams, and no longer picks an unavailable upstream when there's only one weight; random_choose picks the least loaded host when all are busy (#​8159, #​8320, #​8160)
    • with request_buffers / response_buffers unlimited, a body that fails partway is no longer treated as complete (#​8207)
    • connections and sockets are no longer leaked when a protocol upgrade (e.g. WebSocket) fails during setup, or when a handle_response status isn't a number. Thanks @​Version2beta and @​BenMacha! (#​8269, #​8318)
    • HTTP/3 client cancellations are logged at debug level instead of as warnings. Thanks @​larrasket! (#​8135)
  • encode: If-None-Match lists and weak tags get 304s properly (#​8128), HEAD responses no longer get a bogus Content-Length (#​8150), and Accept-Encoding / Cache-Control split across several header lines are all taken into account, with faster header handling in the proxy too. Thanks @​Indra55, @​jayhemnani9910 and @​dunglas! (#​8025)
  • PHP / FastCGI: a Location response without a Status is now a 302 redirect, as CGI specifies (#​8209), and an app that writes more than its declared Content-Length (like a PHP warning after the page) no longer corrupts HTTP/1.1 responses or kills HTTP/2 connections. Thanks @​Sulaiman-Dauda! (#​8212)
  • TLS & ECH:
    • when Caddy rejects Encrypted ClientHello, it now sends retry configs, so clients with stale ECH configs can recover. Thanks @​videah! (#​8142)
    • an ECH public name that also has its own site block keeps that site's TLS settings (#​8156)
    • client_auth modes request and verify_if_given no longer reject clients without a certificate when verifiers are configured (#​8251)
    • a site block spanning several listener addresses no longer lets one listener's TLS connection policy (including client authentication) overwrite another's. Thanks @​steadytao! (#​8192)
    • repeated matcher lines in a TLS policy match block are all applied, not just the first. Thanks @​simonether! (#​8137)
    • merged automation policies keep a specific domain's policy ahead of a wildcard's (#​8287), and an ACME issuer's network_proxy survives re-provisioning (#​8288)
  • Caddyfile:
    • caddy run prints the error again when startup fails, instead of silently exiting with code 1. Thanks @​IndraGunawan! (#​8180)
    • routes in a group that already matched no longer run their matchers, which fixes e.g. try_files {path} {path}.html?{query} =404 returning 404 for everything (#​8189)
    • multiple handle_errors blocks and vars now follow Caddyfile order (#​8195, #​8197)
    • each ?Field default in a header block is checked on its own, and respects match (#​8217)
    • import shows the real OS error for files it can't read (#​8163), negative {args[...]} indices no longer panic (#​8316), and very long heredoc markers no longer make parsing crawl (#​8203, #​8249)
  • file_server: a path below a regular file (/index.php/foo) is a 404 again and works with pass_thru (#​8131); browse handles symlinks in directories with escaped names (#​8152) and offsets past the end (#​8213)
  • templates: template errors no longer keep stale Content-Length / Etag headers (#​8149), bodyless responses no longer get Content-Length: 0 (which broke iOS PWAs) (#​8153), plus fixes for humanize time layouts with colons and front matter closed with ... (#​8215, #​8259)
  • Logging: include of a parent namespace includes its child modules (#​8221), dir_mode from_file no longer creates unusable directories (#​8225), and log routing to a site's logger ignores Host case (#​8176)
  • Admin API: with remote admin access_control, a request is allowed if any permission entry permits it, not just the first (#​8317), and Cache-Control: must-revalidate is recognized alongside other directives (#​8330)
  • Other fixes: caddy hash-password handles Windows line endings and input without a final newline (#​8227), a data race in the basic_auth cache is gone (#​8278), the Windows service no longer gets stuck in START_PENDING (#​8274), and uri strip_prefix / strip_suffix handle percent-escapes and literal % correctly (#​8005, #​8345)
  • Release builds use Go 1.27 (Go 1.26 is still the minimum to build Caddy). (#​8210)

⚠️ Breaking changes

  • Requests with an invalid or dots-only host (like ..) are rejected with 400 on every protocol, before any route runs. Before, HTTP/2 and HTTP/3 also accepted hosts containing / or \. (#​8328)
  • request_body max_size now rejects a request with 413 as soon as its Content-Length is over the limit, even if nothing would have read the body. (#​8337)
  • php_fastcgi sites without an index.php: requests for paths that don't exist are now sent to PHP as index.php, as the documented first_exist_fallback try policy always promised, instead of falling through to file_server and returning 404. Also, PATH_INFO and DOCUMENT_URI are now derived from the normalized path (repeated slashes merged, . segments removed); REQUEST_URI is unchanged.
  • A try_files / file candidate ending in / only matches a directory, so /foo.txt/ no longer matches the file /foo.txt. (#​8326)
  • encode now compresses responses even when the request has Cache-Control: no-transform (a response's no-transform is still honored), and responses that could have been encoded always get Vary: Accept-Encoding. To keep the old behavior: @transformable not header Cache-Control *no-transform* and encode @transformable. Malformed forms like no-cache; no-transform no longer disable compression. (#​8301, #​8025)
  • Stricter config validation. Some configs that were silently accepted (and didn't do what you'd expect) are now errors:
    • more than one expression line in the same matcher set (combine them with &&) (#​8183)
    • unknown TLS curves or protocol_min / protocol_max names, like TLS1.3 instead of tls1.3, which used to be silently ignored (#​8266)
    • a repeated sni_regexp in a TLS policy match block (#​8137)
    • ip_mask log filter sizes out of range, like 33 for IPv4 (#​8241)
    • basic_auth usernames that end up identical after placeholder expansion (#​8315)
    • ports longer than 11 characters (#​8277)
  • Evaluation order now follows the Caddyfile for handle_errors blocks with status codes and for vars with non-path matchers. If you had overlapping codes or set the same variable twice, a different block or value may now win. (#​8195, #​8197)

Security fixes

Thank you to everyone who reported responsibly and helped with patches:

  • caddyhttp: A Host / :authority value with dot segments or slashes could escape the intended directory when used in file paths, like root /srv/sites/{host}, and with php_fastcgi even execute files outside it. Such hosts are now rejected (see above). Thanks @​dunglas. (GHSA-r766-rf9f-588h, #​8328)
  • fastcgi: SCRIPT_FILENAME is now derived from the same normalized path that path matchers see, so a route protected by a path matcher can't be made to run a different script, e.g. with /admin.php/../../other.php. The php_fastcgi rewrite also always runs now (see above). Thanks @​pamnario. (GHSA-f278-mgc7-46j3)
  • fileserver: The file matcher no longer resolves paths like /.env/./ to the regular file, which bypassed path rules such as path *.env. Thanks @​dunglas. (GHSA-25cw-38mq-q7m6, #​8326)
  • rewrite: {http.matchers.file.remainder} is now escaped before rewriting, so double-encoded path info (like ..%252f) can't turn into ../ after path rules have run. Thanks @​dunglas. (GHSA-69hv-5jfc-mvmv, #​8325)
  • fileserver: When neither HOME nor XDG_DATA_HOME is set, Caddy's data directory falls back to ./caddy, and a file_server serving the working directory could expose certificates and private keys. That directory is now always hidden. Thanks @​dunglas. (GHSA-jf74-f69g-hcj9, #​8327)
  • fastcgi: The php_fastcgi trailing-slash redirect for directories with an index.php can no longer be turned into an open redirect to another site. Thanks @​sam-kota. (#​8285)
  • fileserver: Files excluded with hide no longer show up in browse listings, and hidden precompressed sidecars are no longer served. Thanks @​agammann. (#​8155)
  • reverseproxy: Hop-by-hop headers are stripped from 1xx responses and from copy_response_headers in handle_response, completing the fix for CVE-2026-55458. Thanks @​SssiiiSssii1 and @​tomholford. (GHSA-8qx7-j2v2-x6q5, #​8256, #​8270)
  • logging: The query log filter now parses request URIs like the server does, so parameters after a # are redacted too. Thanks @​jayhemnani9910. (#​8255)

⚠️ These security patches may be breaking if your application relies on the buggy behaviors.

🚨 Notice for Caddy plugin maintainers: Dependabot will probably alert you to the security fixes in Caddy and urge you to upgrade it in your go.mod file. Please ONLY upgrade the Caddy dependency if there's a change to an exported API your plugin uses.

Thank you to everyone who was involved in this release, especially our 28 new contributors! 🎉

What's Changed

New Contributors

[!IMPORTANT]
✂ PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • Between 12:00 AM and 03:59 AM, only on Monday (* 0-3 * * 1)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@codecov

codecov Bot commented Nov 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.35%. Comparing base (5b09701) to head (1919be4).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #105   +/-   ##
=======================================
  Coverage   97.35%   97.35%           
=======================================
  Files          28       28           
  Lines        1171     1171           
=======================================
  Hits         1140     1140           
  Misses         31       31           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@renovate
renovate Bot merged commit ae15d35 into main Nov 9, 2026
22 checks passed
@renovate
renovate Bot deleted the renovate/caddy-2.x branch November 9, 2026 04:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants