Caddy Release Notes

Last updated: Jan 7, 2026

  • Jan 6, 2026
    • Parsed from source:
      Jan 6, 2026
    • Detected by Releasebot:
      Jan 7, 2026
    Caddy logo

    Caddy

    v2.11.0-beta.2

    Second beta of 2.11 lands with minor features, enhancements, and a ZeroSSL issuer fix as it nears final release. Highlights include PKI, TLS, logging, and module tooling improvements with a full changelog and contributor notes.

    Welcome to the second beta version of 2.11. We are closer to a final release. This includes some minor new features and enhancements, and a fix for the ZeroSSL API issuer.

    Thank you to everyone who contributed!

    Changelog

    • 8a87bb3 build(deps): bump github.com/smallstep/certificates (#7381)
    • 7b031e1 build(deps): bump the all-updates group across 1 directory with 12 updates (#7421)
    • be5f49f caddyhttp: Fix logging on wildcard sites when SkipUnmappedHosts is true (#7372)
    • 6e0cbd0 caddyhttp: create a placeholder for and log ech status (#7328)
    • 4037d05 caddyhttp: {http.request.body_base64} placeholder (#7367)
    • 7ebe72b caddypki: Add support for multiple intermediates in signing chain (#7057)
    • 3c9c67e caddytls: ECH key rotation (#7356)
    • 374b7a6 caddytls: fix preferred chains options by appending values instead of replacing (#7387)
    • 6a4296b caddytls: panic when using tls.ca_pool.source.http -> tls.ca (#7393)
    • 9eabd44 cmd: Add --json flag to list-modules command (#7409)
    • b2d21f6 go.mod: Upgrade CertMagic and ZeroSSL deps
    • 34fd2df go.mod: update tscert package to latest (aea342f6) (#7397)
    • decc8a4 logging: log_append Early option, Supports {http.response.body} (#7368)
    • 409a072 notify: implement windows service status and error notifications (#7389)
    • 1f1be3f tracing: Add span attributes to tracing module (#7269)

    What's Changed

    • build(deps): bump github.com/smallstep/certificates from 0.28.4 to 0.29.0 by @dependabot[bot] in #7381
    • caddypki: Add support for multiple intermediates in signing chain by @hslatman in #7057
    • caddyhttp: Fix logging on wildcard sites when SkipUnmappedHosts is true by @francislavoie in #7372
    • multiplexing: Introduce packet conn wrappers by @vnxme in #7180
    • docs: add maybe template function documentation by @steffenbusch in #7388
    • caddyhttp: create a placeholder for and log ech status by @WeidiDeng in #7328
    • caddytls: fix preferred chains options by appending values instead of replacing by @okrc in #7387
    • feat: mark Assert* functions as test helpers by @dunglas in #7380
    • caddytls: ECH key rotation by @mholt in #7356
    • caddytls: panic when using tls.ca_pool.source.http -> tls.ca by @Zenexer in #7393
    • notify: implement windows service status and error notifications by @FreyreCorona in #7389
    • caddyhttp: {http.request.body_base64} placeholder by @francislavoie in #7367
    • chore: update tscert package to latest (aea342f6) by @willnorris in #7397
    • logging: log_append Early option, Supports {http.response.body} by @francislavoie in #7368
    • update quic-go to v0.58.0 by @marten-seemann in #7404
    • cmd: add --json flag to list-modules by @pauloappbr in #7409
    • Add span attributes to tracing module by @felix-hilden in #7269
    • readme: fix fence by @mohammed90 in #7416
    • build(deps): bump the all-updates group across 1 directory with 12 updates by @dependabot[bot] in #7421

    New Contributors

    • @okrc made their first contribution in #7387
    • @Zenexer made their first contribution in #7393
    • @FreyreCorona made their first contribution in #7389
    • @pauloappbr made their first contribution in #7409
    • @felix-hilden made their first contribution in #7269

    Full Changelog: v2.11.0-beta.1...v2.11.0-beta.2

    Original source Report a problem
  • Dec 4, 2025
    • Parsed from source:
      Dec 4, 2025
    • Detected by Releasebot:
      Jan 7, 2026
    Caddy logo

    Caddy

    v2.11.0-beta.1

    Caddy 2.11 beta ships with an automated release workflow and broader stability gains. It covers edge case fixes for H2C HTTP/3, named sockets, and config reload nuances, plus logging and dependency updates as prep for a stable release.

    Welcome

    Welcome to the beta version of 2.11. This is the first release made by our new, automated release process developed by @mohammed90 that was carried out and approved entirely by our maintainer team (together with @francislavoie) without intervention from @mholt, the original Caddy author. This represents a significant step forward in project autonomy and growth, ensuring that the project's stability and longevity is not reliant upon a single person.
    This first beta release was primarily to test our new workflow, so there's still a couple things left to do before the stable release.
    Featured here are numerous, mostly minor, bug fixes and enhancements, mostly affecting edge cases or niche corners of the software; for example, proxying H2C or HTTP/3, obscure Caddyfile scenarios, and named socket activation.
    Some notable changes:
    SIGUSR1 can be used to reload configuration only if it was loaded from a file using the CLI, and not changed by the API since then.
    We replaced "lumberjack", our logging library, with a fork "timberjack" that supports the oft-requested time-rolling ability.
    Caddy can now bind listeners with named socket activation.
    Before the final release, we expect ECH key rotation to be enabled as well as a few other patches/features
    Thank you to our sponsors and contributors for all that you do!

    Changelog

    5473eb9 encode: fix response corruption when handle_errors is used (#7235)
    13a4ec7 basicauth: Implement argon2id (#7186)
    6d90c77 build(deps): bump github.com/slackhq/nebula from 1.9.5 to 1.9.7 (#7315)
    eead249 build(deps): bump golang.org/x/crypto from 0.43.0 to 0.45.0 (#7355)
    2d0f3f8 build(deps): bump the actions-deps group with 5 updates (#7237)
    afbdcec build(deps): bump the actions-deps group with 8 updates (#7284)
    cd1c203 build(deps): bump the all-updates group across 1 directory with 2 updates (#7307)
    39357d3 build(deps): bump the all-updates group with 17 updates (#7236)
    786d537 build(deps): bump the all-updates group with 3 updates (#7376)
    07d2aaf build(deps): bump the all-updates group with 4 updates (#7333)
    0ba8786 caddyfile: Allow block to do nothing if nothing passed to import (#7206)
    92c8bc7 caddyfile: fix nested quotes formatted incorrectly by fmt (#7045)
    6d73d85 caddyfile: prevent adding trailing space on line before env variable (#7215)
    d7185fd caddyhttp: Add trusted_proxies_unix for trusting unix socket X-Forwarded-* headers (#7265)
    de6b780 caddyhttp: Add server options keepalive_idle and keepalive_count (#7298)
    e0a8f95 caddyhttp: Normalize (lowercase) {label.N} placeholders
    5e29536 caddyhttp: add replacer placeholders for escaped values (#7181)
    8285eba caddyhttp: allow customizing the Server header (#7338)
    bc0e184 caddyhttp: omit unnecessary reassignment (#7276)
    3553cfb caddyhttp: remove redundant middleware next copy (#7217)
    1ce2a13 caddyhttp: wrap accepted connection to suppress tls.ConnectionState (#7247)
    d9cc24f caddypki: Disable internal auto-CA when auto_https is disabled (fix #7211) (#7238)
    1e82f96 caddypki: check intermediate lifetime to actual root cert lifetime (#7272)
    38848f7 caddytls: Allow disabling distributed solving (except http-01)
    ddec183 caddytls: correct documentation of LeafFolderLoader (#7327)
    f5c3094 cmd: prevent commas in header values from being split (#7268)
    65e0ddc core: Reloading with SIGUSR1 if config never changed via admin (#7258)
    b3f2db2 core: custom slog handlers for modules (log contextual data) (#7346)
    b2ab419 core: use reflect.TypeFor to check for encoding/json.RawMessage (#7274)
    806fef8 encode: add graphql-response header to list (#7214)
    2cb4267 encode: modernize, replace HasSuffix+TrimSuffix with CutSuffix (#7357)
    b462615 fileserver: set Content-Length for precompressed files (#7251)
    0c8798f go.mod: update quic-go to v0.54.1 (#7273)
    3c003de httpcaddyfile: Add missing DNS challenge check for acme_dns (#7270)
    2f1d270 httpcaddyfile: Map default_bind to BindHost in globalACMEDefaults (#7278)
    a7885aa intercept: use already buffered response if possible when intercepting (#7028)
    156ce99 listeners: Add support for named socket activation (#7243)
    39ace45 logging: Adjustments to BufferedLog to keep logs in the correct order (#7257)
    012b4b3 logging: Buffer the logs before config is loaded (#7245)
    10ac7da logging: Switch from lumberjack to timberjack, add time-rolling options (#7244)
    f5f25d8 logging: fix multiple regexp filters on same field (fixes #7049) (#7061)
    595aab8 metrics: resolve per-host inifinite cardinality (#7306)
    57587ed refactor: use reflect.TypeFor (#7313)
    2ec28bc reverse_proxy: use http1 for outbound tls requests with placeholder that are likely websockets (#7296)
    a6da1ac reverse_proxy: use interfaces to modify the behaviors of the transports (#7353)
    67a9e06 reverseproxy: Fix retries for requests with bodies (#7360)
    7fb39ec reverseproxy: Use http1.1 upgrade for websocket for extended connect of http2 and http3 (#7305)
    8aca108 reverseproxy: do not disable keepalive if proxy protocol is used (#7300)
    abe0aca reverseproxy: set default values for keepalive if only some of them are set (#7318)
    1e21b66 reverseproxy: use http.Protocols to handle h2c requests (#6990)
    b54e870 tracing: switch to autoexport for OpenTelemetry span exporter (#7317)

    What's Changed

    caddyhttp: add replacer placeholders for escaped values by @Qusic in #7181
    AI assistance disclosure by @mholt in #7212
    caddyfile: Prevent trailing space on line before env variable - Fixes #6881 by @arpansaha13 in #7215
    add: encode header Content-Type graphql-response by @aro-lew in #7214
    caddyhttp: Removing redundant middleware next copy by @maxcelant in #7217
    build(deps): bump the all-updates group with 17 updates by @dependabot[bot] in #7236
    build(deps): bump the actions-deps group with 5 updates by @dependabot[bot] in #7237
    encode: fix response corruption when handle_errors is used by @Siomachkin in #7235
    Fix PKI creation when auto_https is disabled (#7211) by @Siomachkin in #7238
    logging: Buffer the logs before config is loaded by @francislavoie in #7245
    fileserver: set Content-Length for precompressed files by @WeidiDeng in #7251
    refactor: use WaitGroup.Go to simplify code by @mickychang9 in #7253
    caddyfile: Allow block to do nothing if nothing passed to import by @BeeJay28 in #7206
    logging: Adjustments to BufferedLog to keep logs in the correct order by @francislavoie in #7257
    caddyhttp: Prevent commas in header values from being split in CLI commands by @gilbsgilbs in #7268
    update quic-go to v0.54.1 by @marten-seemann in #7273
    chore: ugh, lint fix... by @mohammed90 in #7275
    caddypki: check intermediate lifetime to actual root cert lifetime by @u5surf in #7272
    refactor: omit unnecessary reassignment by @asttool in #7276
    core: use reflect.TypeFor to check for encoding/json.RawMessage by @WeidiDeng in #7274
    core: Reloading with SIGUSR1 if config never changed via admin by @francislavoie in #7258
    build(deps): bump the actions-deps group with 8 updates by @dependabot[bot] in #7284
    httpcaddyfile: Add missing DNS challenge check for acme_dns by @rightaditya in #7270
    httpcaddyfile: Map default_bind to BindHost in globalACMEDefaults by @Monviech in #7278
    Argon2id Support for Basic Auth by @GreyXor in #7186
    update quic-go to v0.55.0 by @marten-seemann in #7288
    reverse_proxy: use http1 for outbound tls requests with placeholder t… by @WeidiDeng in #7296
    caddyhttp: Add server options keepalive_idle and keepalive_count by @joshuamcbeth in #7298
    chore: fix some comments by @wyrapeseed in #7303
    logging: Switch from lumberjack to timberjack, add time-rolling options by @aeris in #7244
    reverseproxy: Use http1.1 upgrade for websocket for extended connect of http2 and http3. by @tonyb486 in #7305
    caddyhttp: Add trusted_proxies_unix for trusting unix socket X-Forwarded-* headers by @cseufert in #7265
    caddyhttp: wrap accepted connection to suppress tls.ConnectionState by @WeidiDeng in #7247
    logging: fix multiple regexp filters on same field (fixes #7049) by @s2010 in #7061
    intercept: use already buffered response if possible when intercepting by @WeidiDeng in #7028
    listeners: Add support for named socket activation by @Siomachkin in #7243
    reverseproxy: do not disable keepalive if proxy protocol is used by @WeidiDeng in #7300
    metrics: resolve per-host inifinite cardinality by @mohammed90 in #7306
    reverseproxy: use http.Protocols to handle h2c requests by @WeidiDeng in #6990
    refactor: use reflect.TypeFor by @wyrapeseed in #7313
    build(deps): bump the all-updates group across 1 directory with 2 updates by @dependabot[bot] in #7307
    build(deps): bump github.com/slackhq/nebula from 1.9.5 to 1.9.7 by @dependabot[bot] in #7315
    feat: switch to autoexport for OpenTelemetry span exporter by @PKeidel in #7317
    reverse_proxy: set default values for keepalive if only some of them are set by @WeidiDeng in #7318
    fix quote within quotes formatted incorrectly by fmt by @keystroke3 in #7045
    caddytls: correct documentation of LeafFolderLoader by @mohammed90 in #7327
    fix golangci-lint error G602 in caddyhttp by @cdenicola in #7334
    feat: allow customizing the Server header by @dunglas in #7338
    update quic-go to v0.56.0, enable qlog for HTTP/3 by @marten-seemann in #7345
    build(deps): bump the all-updates group with 4 updates by @dependabot[bot] in #7333
    feat: custom slog handlers for modules (log contextual data) by @dunglas in #7346
    ci: implement new release flow by @mohammed90 in #7341
    reverse_proxy: use interfaces to modify the behaviors of the transports by @WeidiDeng in #7353
    build(deps): bump golang.org/x/crypto from 0.43.0 to 0.45.0 by @dependabot[bot] in #7355
    update quic-go to v0.57.0 by @marten-seemann in #7359
    refactor: replace HasSuffix+TrimSuffix with CutSuffix by @ledigang in #7357
    Fix retries for requests with bodies by @chebyrash in #7360
    build(deps): bump the all-updates group with 3 updates by @dependabot[bot] in #7376
    ci: escape backticks in changelogs embedded in JS by @mohammed90 in #7382

    New Contributors

    @Qusic made their first contribution in #7181
    @arpansaha13 made their first contribution in #7215
    @aro-lew made their first contribution in #7214
    @maxcelant made their first contribution in #7217
    @Siomachkin made their first contribution in #7235
    @mickychang9 made their first contribution in #7253
    @asttool made their first contribution in #7276
    @rightaditya made their first contribution in #7270
    @Monviech made their first contribution in #7278
    @wyrapeseed made their first contribution in #7303
    @aeris made their first contribution in #7244
    @tonyb486 made their first contribution in #7305
    @cseufert made their first contribution in #7265
    @s2010 made their first contribution in #7061
    @PKeidel made their first contribution in #7317
    @cdenicola made their first contribution in #7334
    @ledigang made their first contribution in #7357
    @chebyrash made their first contribution in #7360

    Full Changelog: v2.10.2...v2.11.0-beta.1

    Original source Report a problem
  • Aug 23, 2025
    • Parsed from source:
      Aug 23, 2025
    • Detected by Releasebot:
      Jan 7, 2026
    Caddy logo

    Caddy

    v2.10.2

    This is a hotfix release to fix a couple critical issues from v2.10.1

    What's Changed

    • http: Make logger first, before TLS provisioning by @francislavoie in #7198
    • httpcaddyfile: Fix acme_dns regression by @francislavoie in #7199
    • caddyfile: Fix importing nested tokens for {block} by @BeeJay28 in #7189

    Changelog

    • 551f793 caddyfile: Fix importing nested tokens for {block} (#7189)
    • 16fe83c http: Make logger first, before TLS provisioning (#7198)
    • 4564261 httpcaddyfile: Fix acme_dns regression (#7199)

    New Contributors

    • @BeeJay28 made their first contribution in #7189

    Full Changelog: v2.10.1...v2.10.2

    Original source Report a problem
  • Aug 22, 2025
    • Parsed from source:
      Aug 22, 2025
    • Detected by Releasebot:
      Jan 7, 2026
    Caddy logo

    Caddy

    v2.10.1

    Caddy drops a major patch with wide refinements, bug fixes, and dependency upgrades sparked by broader contributions. It adds .avif support, TLS keepalive tweaks, and admin and proxy improvements while upgrading quic-go and other deps. This is a real shipped release.

    This is probably our biggest patch release ever -- not that lots of things were broken, but there's lots of refinement happening thanks to broader adoption and contributions from many more people. Just look at the New Contributors below!

    Anyway, this release does contain some bug fixes and dependency upgrades which we hope will serve you well. Let us know if there's any issues! And thank you to all who contributed, especially our reliable maintainer team!

    This version of Caddy requires Go v1.25.0 or newer.

    What's Changed

    • update quic-go to v0.51.0 by @marten-seemann in #6972
    • forwardproxy: reference correct field name in LoadModule by @mohammed90 in #6978
    • fix: Remove nil arg from zapslog.NewHandler call by @IndraGunawan in #6984
    • fileserver: Add support for .avif image format by @steffenbusch in #6988
    • reverseproxy: use DialTLSContext for TLS if servername has placeholder by @WeidiDeng in #6955
    • admin: Make sure that any admin routers are provisioned when local/re… by @Compy in #6997
    • log: default logger should respect {in,ex}clude by @mohammed90 in #6995
    • Move local admin server replacement logic below data structure initia… by @Compy in #7004
    • acme_server: fix policy parsing in caddyfile by @mohammed90 in #7006
    • implement Unwrap for interceptedResponseHandler by @WeidiDeng in #7016
    • fileserver: map invalid path errors to fs.ErrInvalid, and return 400 … by @Compy in #7017
    • caddyhttp: fix route sort by comparing paths without wildcard if they don't shar… by @WeidiDeng in #7015
    • refactor: use maps.Copy for cleaner map handling by @eveneast in #7009
    • refactor: use slices.Contains to simplify code by @tongjicoder in #7039
    • chore: upgrade .golangci.yml and workflow to v2 by @mohammed90 in #6924
    • build(deps): bump golangci/golangci-lint-action from 6 to 8 by @dependabot[bot] in #7044
    • fix: crash - null check on event origin by @suxatcode in #7047
    • fix: prevent error handler from overriding sub handler matchers by @Hellio404 in #6999
    • client_auth: wire up leaf verifier Caddyfile by @mohammed90 in #6772
    • caddyfile: reject blocks in log_skip directive by @IwatsukaYura in #7056
    • build(deps): bump github.com/cloudflare/circl from 1.6.0 to 1.6.1 by @dependabot[bot] in #7058
    • cmd: fix Commands function not returning all registered commands by @hslatman in #7059
    • ci: add dep review, OSSF scorecard actions by @mohammed90 in #7063
    • ci: add {base,head}-ref to dep review check by @mohammed90 in #7064
    • core: clean up new config if it failed to run by @WeidiDeng in #7068
    • chore: apply security best practices for CI by @mohammed90 in #7066
    • refactor: use the built-in max/min to simplify the code by @xiaoxiangirl in #7081
    • [ADD] sort buttons in grid mode by @filipRatajczak in #7089
    • update quic-go to v0.53.0 by @marten-seemann in #7094
    • refactor: replace HasPrefix+TrimPrefix with CutPrefix by @gopherorg in #7095
    • docs: fix some minor issues in the comments by @mountdisk in #7101
    • httpcaddyfile: Validates TLS DNS challenge options by @francislavoie in #7099
    • chore: fix struct name in comment by @bytetigers in #7114
    • reverse proxy: validate versions in http transport by @WeidiDeng in #7112
    • chore: fix function in comment by @bytesingsong in #7121
    • Fix: Support placeholders in header replacement search patterns by @zongzewu23 in #7117
    • fileserver: specify license for embedded JavaScript by @infertux in #7127
    • fix dead link by @eeemmmmmm in #7136
    • update quic-go to v0.54.0 by @marten-seemann in #7138
    • chore: fix minor issue in comment by @pingshuijie in #7140
    • refactor: use slices.Equal to simplify code by @minxinyi in #7141
    • ci: reduce dependabot spam by @mohammed90 in #7078
    • fix(provisioning): Context.App or Context.AppIfConfigured will return (val, nil) even if the app failed to provision or validate the first time by @alexandre-daubois in #7070
    • build(deps): bump the actions-deps group with 6 updates by @dependabot[bot] in #7142
    • Use KeepAliveConfig to pass keepalive_interval to listener's accepted sockets by @joshuamcbeth in #7151
    • build(deps): bump the all-updates group across 1 directory with 17 updates by @dependabot[bot] in #7155
    • cmd: Allow caddy adapt to read from stdin by @bosdhill in #7163
    • feat: add bcrypt cost parameter to hash-password by @GreyXor in #7149
    • fix typo in bcrypt cost flag name by @GreyXor in #7168
    • chore: fix inconsistent function name in comment by @youzichuan in #7174
    • caddytls: fix regression in external certificate manager support by @quagsirus in #7179
    • http: free up quic listener when stopping by @WeidiDeng in #7177
    • chore: bump Go to v1.25 by @dunglas in #7184
    • caddyhttp: refactor to use reflect.TypeFor by @cuiweixie in #7187
    • refactor: use a more modern writing style to simplify code by @joemicky in #7182
    • http: disable keepalive when KeepAliveInterval is negative by @WeidiDeng in #7158
    • http: clean up listeners if some of the listeners fail to bind by @WeidiDeng in #7176
    • reverse_proxy: use the new KeepAliveConfig to set probe interval by @WeidiDeng in #7157
    • ci: set proper build tags in golangci and minor cleanup by @dunglas in #7183
    • doc: Add a few lines about Etag file content by @Pizmovc in #7173
    • file_server: set Range header for precompressed static files to force Content Length header to appear by @WeidiDeng in #7042
    • caddyhttp: use the new http.Protocols to handle h1, h2 and h2c requests by @WeidiDeng in #6961
    • Changelog

    44d078b acme_server: fix policy parsing in caddyfile (#7006)
    320c572 admin: Make sure that any admin routers are provisioned when local/re… (#6997)
    49dac61 bcrypt: add cost parameter to hash-password (#7149)
    4bfc3b9 bcrypt: wrong cost flag name (#7168)
    4b01d77 build(deps): bump github.com/cloudflare/circl from 1.6.0 to 1.6.1 (#7058)
    45c9341 build(deps): bump golangci/golangci-lint-action from 6 to 8 (#7044)
    5bc2afb build(deps): bump the actions-deps group with 6 updates (#7142)
    007f406 build(deps): bump the all-updates group across 1 directory with 17 updates (#7155)
    8524386 caddyhttp: Compare paths w/o wildcard if prefixes differ (#7015)
    7590c9c caddyhttp: Free up quic listener when stopping (#7177)
    b15ed9b caddyhttp: refactor to use reflect.TypeFor (#7187)
    14a63a2 caddyhttp: use the new http.Protocols to handle h1, h2 and h2c requests (#6961)
    731e6c2 caddytls: Improve ECH error logging (close #7152)
    105eee6 caddytls: Set local_ip, not remote_ip (#6952)
    b898873 caddytls: fix regression in external certificate manager support (#7179)
    1481c04 caddytls: wire up client_auth leaf verifier Caddyfile (#6772)
    19ff47a cmd: Allow caddy adapt to read from stdin (#7163)
    e633d01 cmd: fix Commands function not returning all registered commands (#7059)
    7099892 core: Check for nil event origin (#7047)
    3d0b4fa core: Clean up new config if it failed to run (#7068)
    051e73a core: Replace admin server later in provisionContext (#7004)
    fe41ff3 core: Save app provisioning errors with context (#7070)
    e4447c4 core: Use KeepAliveConfig to pass keepalive_interval to listener's accepted sockets (#7151)
    b9710c6 fileserver: Add a few doc lines about Etag file content (#7173)
    3b4d966 fileserver: Add sort buttons in grid mode (#7089)
    54d03ce fileserver: Add support for .avif image format (#6988)
    790f3e0 fileserver: denote license for embedded JavaScript for LibreJS (#7127)
    94147ca fileserver: map invalid path errors to fs.ErrInvalid, and return 400 for any invalid path errors. (close #7008) (#7017)
    67debd0 fileserver: set Range header for precompressed static files to force Content Length header to appear (#7042)
    89ed5f4 fix: Remove nil arg from zapslog.NewHandler call (#6984)
    3723e89 go.mod: Upgrade CertMagic to v0.24.0
    3bd4135 go.mod: Upgrade dependencies
    a6d488a go.mod: update quic-go to v0.51.0 (#6972)
    11c6dae go.mod: update quic-go to v0.53.0 (#7094)
    bbf1dfc headers: Support placeholders in replacement search patterns (#7117)
    f11c780 http: clean up listeners if some of the listeners fail to bind (#7176)
    fdf6108 http: disable keepalive when KeepAliveInterval is negative (#7158)
    5b727bd httpcaddyfile: Allow naked acme_dns if dns is set (fix #7091)
    0badb07 httpcaddyfile: Fix generated config related to ACME global options
    092913a httpcaddyfile: Prevent error handler from overriding sub-handler matchers (#6999)
    77dd12c httpcaddyfile: Validates TLS DNS challenge options (#7099)
    0f209f6 httpcaddyfile: reject blocks in log_skip directive (#7056)
    716d72e intercept: implement Unwrap for interceptedResponseHandler (#7016)
    9f71483 log: default logger should respect {in,ex}clude (#6995)
    33c88bd refactor: replace HasPrefix+TrimPrefix with CutPrefix (#7095)
    ab3b2d6 refactor: use slices.Equal to simplify code (#7141)
    1c596e3 reverse_proxy: use the new KeepAliveConfig to set probe interval (#7157)
    aa3d20b reverseproxy: Use DialTLSContext if ServerName has placeholder (#6955)
    737936c reverseproxy: reference correct field name in LoadModule (#6978)
    1209b5c reverseproxy: validate versions in http transport (#7112)

    New Contributors

    @IndraGunawan made their first contribution in #6984
    @Compy made their first contribution in #6997
    @eveneast made their first contribution in #7009
    @tongjicoder made their first contribution in #7039
    @suxatcode made their first contribution in #7047
    @Hellio404 made their first contribution in #6999
    @IwatsukaYura made their first contribution in #7056
    @xiaoxiangirl made their first contribution in #7081
    @filipRatajczak made their first contribution in #7089
    @gopherorg made their first contribution in #7095
    @mountdisk made their first contribution in #7101
    @bytetigers made their first contribution in #7114
    @bytesingsong made their first contribution in #7121
    @zongzewu23 made their first contribution in #7117
    @infertux made their first contribution in #7127
    @eeemmmmmm made their first contribution in #7136
    @pingshuijie made their first contribution in #7140
    @minxinyi made their first contribution in #7141
    @alexandre-daubois made their first contribution in #7070
    @joshuamcbeth made their first contribution in #7151
    @bosdhill made their first contribution in #7163
    @GreyXor made their first contribution in #7149
    @youzichuan made their first contribution in #7174
    @quagsirus made their first contribution in #7179
    @cuiweixie made their first contribution in #7187
    @joemicky made their first contribution in #7182
    @Pizmovc made their first contribution in #7173

    Full Changelog: v2.10.0...v2.10.1

    Original source Report a problem
  • Apr 18, 2025
    • Parsed from source:
      Apr 18, 2025
    • Detected by Releasebot:
      Jan 7, 2026
    Caddy logo

    Caddy

    v2.10.0

    Caddy 2.10 brings ECH for encrypted ClientHello, post-quantum key exchange, flexible ACME profiles, a Via header update, global DNS, wildcard certs by default, libdns 1.0 beta, and Go version tightening for faster security updates. A solid step forward for privacy and reliability.

    Caddy release notes

    Caddy 2.10 is here! Aside from bug fixes, this release features:

    • Encrypted ClientHello (ECH): This new technology encrypts the last plaintext portion of a TLS connection: the ClientHello, which includes the domain name being connected to. The draft spec for ECH is almost finalized, so we can now support this privacy feature for TLS. This is a powerful but nuanced capability; we highly recommend reading the ECH documentation on our website.
    • Post-quantum (PQC) key exchange: Caddy now supports the standardized x25519mlkem768 cryptographic group by default.
    • ACME profiles: ACME profiles are an experimental draft that allow you to choose properties of your certificates with more flexibility than traditional CSR methods. For example, Let's Encrypt will issue 6-day certificates under a certain profile. Caddy may eventually use that profile by default.
    • Via header: The reverse proxy now sets a Via header instead of a duplicate Server header.
    • Global DNS provider: You can now specify a default "global" DNS module to use instead of having to configure it locally in every part of your config that requires a DNS provider (for example, ACME DNS challenges, and ECH). This is the dns global option in the Caddyfile, or in JSON config, it's the dns parameter in the tls app configuration.
    • Wildcards used by default: Previously, Caddy would obtain individual certificates for every domain in your config literally; now wildcards, if present, will be utilized for subdomains, rather than obtaining individual certificates. This change was motivated by the novel possibility for subdomain privacy afforded by ECH. It can be overridden with tls force_automate in the Caddyfile. The experimental auto_https prefer_wildcard option has been removed.
    • libdns 1.0 APIs: Many of you use DNS provider modules to solve ACME DNS challenges or to enable dynamic DNS. They implement interfaces defined by libdns to get, set, append, and delete DNS records. After 5 years of production experience, including lessons learned with ECH, libdns APIs have been updated and 1.0 beta has been tagged. DNS provider packages will need to update their code to be compatible, which will help ensure stability and well-defined semantics for the future. Several packages have already updated or are in the process of updating (cloudflare, rfc2136, and desec to name a few).
    • Global dns config: Now that several components of Caddy configuration may affect DNS records (ACME challenges, ECH publication, etc.), there is a new dns global option that can be used to specify your DNS provider config in a single place. This prevents repetition of credentials for servers where all the domains are managed by a single DNS provider.
    • Thank you to the many contributors who have helped to make this possible! 🎉 🥳 🍾
    • ⚠️ While have traditionally supported the last 2 minor Go versions to accommodate some distribution / package manager policies, we now only support the latest minor Go version. The privacy and security benefits added in new Go versions (such as post-quantum cryptography) are worth making available to everyone as soon as possible, rather than holding back the entire user base or maintaining multiple code compilation configurations.

    Encrypted ClientHello (ECH) details

    (This is a brief overview. We recommend reading the full documentation.)
    Typically, server names (domain names, or "SNI") are sent in the plaintext ClientHello when establishing TLS connections. With ECH, the true server name is encrypted (and wrapped) by an "outer" ClientHello which has a generic SNI of your choosing. With many sites on the same server sharing the same outer SNI, both clients and the server have more privacy related to domain names.
    Caddy implements fully automated ECH, meaning that it generates (and soon, rotates), publishes, and serves ECH configurations simply by specifying a DNS provider, and the outer/public domain name to use.
    Fully automated ECH requires a DNS module built into your Caddy binary. In order for a client, such as a browser, to know it can use ECH, and what parameters to use, the server's ECH configuration must be published. This config includes the public name, cryptographic parameters, and a public key for encrypting the inner ClientHello. By convention, browsers read the standardized HTTPS-type DNS record containing a ech SvcParamKey. Caddy sets this DNS record for all domains being protected, but it needs that DNS provider module plugged in and configured in order to do this. If you are already using the DNS ACME challenge, you should already have a DNS provider plugged in. If you prefer to build Caddy from source with a DNS module, it's easy with xcaddy, for example: $ xcaddy build --with github.com/caddy-dns/cloudflare
    The minimum config needed to enable ClientHello is also the recommended config, as it maximizes privacy benefits in most situations. You just need the ech global option and a DNS provider specified. Here's an example using Cloudflare as the nameserver:
    Caddyfile:
    {
    debug # not required; recommended while testing
    dns cloudflare {env.CLOUDFLARE_API_KEY}
    ech ech.example.net
    }
    example.com {
    respond "Hello there!"
    }
    This protects all your sites (example.com in this case) behind the public name of ech.example.net. (As another example, Cloudflare uses cloudflare-ech.com for all the sites it serves. We recommend choosing a single public domain and use it to protect all your sites.)
    The outer/public name you choose should point to your server. Caddy will obtain a certificate for this name in order to facilitate safe, reliable connections for clients when needed. Without a certificate, clients may be forced to connect insecurely, or fail to connect at all, in some cases, which not only leaves them vulnerable, but also risks exposing the names of your server's sites.
    Caddy then uses the specified DNS provider to publish the ECH config(s) for your various site names. It creates (or augments) HTTPS-type records for the domains of your sites (not your ECH public name). Note that DNS provider modules are independently-maintained, and may not have been tested for compatibility with HTTPS-type records. Please contact your module's maintainers if you experience issues.
    If you have more advanced configuration needs, you can use the JSON configuration (more details coming soon; for now, see #6862 or look at the source code; or use caddy adapt to convert a Caddyfile to JSON).
    Testing and verifying Encrypted ClientHello
    First make sure Caddy runs successfully with ECH enabled (and a DNS module) in the config. You should see logs that it is generating an ECH config and publishing it to your domain name(s).
    You will need to use a client that supports ECH. Some custom builds of curl do, and Firefox and modern Chrome-based browsers do as well, but you need to enable DNS-over-HTTPS or DNS-over-TLS first (since, obviously, querying DNS in plaintext for a protected domain name will expose the domain and defeat the purpose of ECH).
    If reusing an existing domain name, clear your DNS cache. Firefox has a way of doing this for its cache at about:networking#dns.
    Once you have a suitable client, use Wireshark to capture network packets as you load your site. You should see only the outer/public name as SNI (ServerName Indicator) values in the packet capture. If at any time you see the true site name, ECH is not working properly -- it could be a client or server issue. Before filing a bug, please try to pinpoint it as a server issue first. But definitely report server bugs! Thank you!
    (Note that ECH is not automatically published for CNAME'd domains, and the domain must already have a record in the zone.)

    Commits

    • Beta 1:
      • 96c5c55 admin: fix index validation for PUT requests (#6824)
      • 3644ee3 build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#6876)
      • eacd772 build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 (#6871)
      • 9996d6a build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 (#6814)
      • 1115158 caddyhttp: ResponseRecorder sets stream regardless of 1xx
      • 8861eae caddytest: Support configuration defaults override (#6850)
      • d7764df caddytls: Encrypted ClientHello (ECH) (#6862)
      • a807fe0 caddytls: Enhance ECH documentation
      • bc3d497 caddytls: Fix broken refactor
      • 7b8f350 caddytls: Fix sni_regexp matcher to obtain layer4 contexts (#6804)
      • 2c4295e caddytls: Initial support for ACME profiles
      • d7872c3 caddytls: Refactor sni matcher (#6812)
      • 172136a caddytls: Support post-quantum key exchange mechanism X25519MLKEM768
      • 066d770 cmd: automatically set GOMEMLIMIT (#6809)
      • 1f35a8a fastcgi: improve parsePHPFastCGI docs (#6779)
      • 22563a7 file_server: use the UTC timezone for modified time (#6830)
      • cfc3af6 fix: update broken link to Ardan Labs (#6800)
      • 99073ea go.mod: Upgrade CertMagic to v0.21.7
      • 1641e76 go.mod: Upgrade dependencies
      • 0d7c639 go.mod: remove glog dependency (#6838)
      • 932dac1 logging: Always set fields func; fix #6829
      • 9e0e5a4 logging: Fix crash if logging error is not HandlerError (#6777)
      • 904a0fa reverse_proxy: re-add healthy upstreams metric (#6806)
      • e7da3b2 reverseproxy: Via header (#6275)
      • 9283770 reverseproxy: ignore duplicate collector registration error (#6820)
    • Beta 2:
      • f4432a3 caddyfile: add error handling for unrecognized subdirective/options in various modules (#6884)
      • 84364ff caddypki: Remove lifetime check at Caddyfile parse (fix #6878)
      • adbe7f8 caddytls: Only make DNS solver if not already set (fix #6880)
      • d57ab21 caddytls: Pointer receiver (fix #6885)
      • 4ebcfed caddytls: Reorder provisioning steps (fix #6877)
      • a686f7c cmd: Only set memory/CPU limits on run (fix #6879)
      • 1987620 cmd: Promote undo maxProcs func to caller
      • 220cd1c reverseproxy: more comments about buffering and add new tests (#6778)
    • Beta 3:
      • b3e692e caddyfile: Fix formatting for backquote wrapped braces (#6903)
      • 55c89cc caddytls: Convert AP subjects to punycode
      • 1f8dab5 caddytls: Don't publish ECH configs if other records don't exist
      • 782a3c7 caddytls: Don't publish HTTPS record for CNAME'd domain (fix #6922)
      • 49f9af9 caddytls: Fix TrustedCACerts backwards compatibility (#6889)
      • e276994 caddytls: Initialize permission module earlier (fix #6901)
      • 39262f8 caddytls: Minor fixes for ECH
      • 1735730 core: add modular network_proxy support (#6399)
      • 86c620f go.mod: Minor dependency upgrades
      • af2d33a headers: Allow nil HeaderOps (fix #6893)
      • dccf3d8 requestbody: Add set option to replace request body (#5795)
      • 2ac09fd requestbody: Fix ContentLength calculation after body replacement (#6896)
    • v2.10.0:
      • f297bc0 admin: Remove host checking for UDS (close #6832)
      • 0b2802f build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 (#6960)
      • 5be77d0 caddyauth: Set authentication provider error in placeholder (#6932)
      • b06a949 caddyhttp: Document side effect of HTTP/3 early data (close #6936)
      • 35c8c2d caddytls: Add remote_ip to HTTP cert manager (close #6952)
      • fb22a26 caddytls: Allow missing ECH meta file
      • 1bfa111 caddytls: Prefer managed wildcard certs over individual subdomain certs (#6959)
      • ea77a9a caddytls: Temporarily treat "" and "@" as equivalent for DNS publication
      • 5a6b2f8 events: Refactor; move Event into core, so core can emit events (#6930)
      • 137711a go.mod: Upgrade acmez and certmagic
      • 9becf61 go.mod: Upgrade to libdns 1.0 beta APIs (requires upgraded DNS providers)
      • 6c38ae7 reverseproxy: Add valid Upstream to DialInfo in active health checks (#6949)
    • What's Changed
      • docs: improve parsePHPFastCGI docs by @dunglas in #6779
      • Fixes crash if logging error is not HandlerError by @kkroo in #6777
      • chore: update quic-go to v0.49.0 by @marten-seemann in #6803
      • chore: don't use deprecated archives.format_overrides.format by @mohammed90 in #6807
      • caddytls: Fix sni_regexp matcher to obtain layer4 contexts by @vnxme in #6804
      • feat: automatically set GOMEMLIMIT by @dunglas in #6809
      • caddytls: Refactor sni matcher by @vnxme in #6812
      • reverse_proxy: re-add healthy upstreams metric by @mohammed90 in #6806
      • fix: update broken link to Ardan Labs by @sbruens in #6800
      • build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 by @dependabot in #6814
      • reverseproxy: ignore duplicate collector registration error by @mohammed90 in #6820
      • fix: fix index validation for PUT requests by @debug-ing in #6824
      • file_server: use the UTC timezone for modified time by @WeidiDeng in #6830
      • feat/tests: tests for error handling & metrics in admin endpoints by @gdhameeja in #6805
      • chore: upgrade Go version to 1.24 by @mohammed90 in #6839
      • remove glog dependency by @Ns2Kracy in #6838
      • update quic-go to v0.50.0 by @marten-seemann in #6854
      • Support Caddy Test Configuration Defaults Override. by @baruchyahalom in #6850
      • chore: upgrade cobra by @mohammed90 in #6868
      • build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 by @dependabot in #6871
      • caddytls: Encrypted ClientHello (ECH) by @mholt in #6862
      • build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 by @dependabot in #6876
      • docs: replaced the name and twitter link by @sashaphmn in #6874
      • ci: allow using the toolchain Go "toolchain" by @dunglas in #6846
      • chore: more comments about reverse_proxy buffering and add new tests by @WeidiDeng in #6778
      • Add error handling for unrecognized subdirective/options by @steffenbusch in #6884
      • Fix TrustedCACerts backwards compatibility by @jjiang-stripe in #6889
      • requestbody: Add replace for optional body replacement by @AdrienPensart in #5795
      • requestbody: Fix ContentLength calculation after body replacement by @steffenbusch in #6896
      • Fix caddy fmt breaks backquote wrapped braces in template by @keystroke3 in #6903
      • update quic-go to v0.50.1 by @marten-seemann in #6918
      • core: add modular network_proxy support by @mohammed90 in #6399
      • events: Refactor; move Event into core, so core can emit events by @mholt in #6930
      • chore: fix comment by @riyueguang in #6950
      • bug: Fix the incorrect parameter order by @cuishuang in #6951
      • Add a valid Upstream to the DialInfo when doing active health checks by @jbro in #6949
      • caddyauth: Set authentication provider error in placeholder by @steffenbusch in #6932
      • build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 by @dependabot in #6960
      • caddytls: Prefer managed wildcard certs over individual subdomain certs by @mholt in #6959

    New Contributors

    • @sbruens made their first contribution in #6800
    • @debug-ing made their first contribution in #6824
    • @Ns2Kracy made their first contribution in #6838
    • @baruchyahalom made their first contribution in #6850
    • @sashaphmn made their first contribution in #6874
    • @AdrienPensart made their first contribution in #5795
    • @keystroke3 made their first contribution in #6903
    • @riyueguang made their first contribution in #6950

    Full Changelog: v2.9.1...v2.10.0

    Original source Report a problem
  • Jan 8, 2025
    • Parsed from source:
      Jan 8, 2025
    • Detected by Releasebot:
      Jan 7, 2026
    Caddy logo

    Caddy

    v2.9.1

    Patch release fixes FastCGI, HTTP/3 and unix sockets plus log and ARI edge case tweaks. It also adds Caddyfile support for header directive response matching. Thanks to all contributors; this ships improvements for users.

    This is a patch release fixing a few issues related to FastCGI, HTTP/3 and unix sockets, log file permissions, repeated TERM signals, and an ARI edge case. It also adds Caddyfile support for response matching in the header directive.
    Thanks to everyone who reported bugs and helped with fixes!
    Changelog
    34cff4a core: Only initiate exit once (should fix #6707)
    50778b5 fix: disable h3 for unix domain socket (#6769)
    0e570e0 go.mod: Upgrade CertMagic to 0.21.6 (fix ARI handshake maintenance)
    e48b758 header: match subdirective for response matching (#6765)
    1f927d6 log: Only chmod if permission bits differ; make log dir (#6761)
    1bd567d reverseproxy: buffer requests for fastcgi by default (#6759)
    What's Changed
    reverse proxy: fastcgi buffer requests for fastcgi by default by @WeidiDeng in #6759
    fix: disable h3 for unix domain socket by @Geun-Oh in #6769
    log: Only chmod if permission bits differ by @mholt in #6761
    header: match subdirective for response matching by @lilnasy in #6765
    New Contributors
    @Geun-Oh made their first contribution in #6769
    @lilnasy made their first contribution in #6765
    Full Changelog: v2.9.0...v2.9.1

    Original source Report a problem

This is the end. You've seen all the release notes in this feed!

Related vendors