/oss · 17 merged

caddyserver/caddy

A popular web server that runs websites and sets up their security certificates for you.

the project on GitHub (opens in a new tab)
  1. 20 Oct 2026

    Page headers end at the right line in templates

    What was broken
    A page can start with a header block that ends with three dots. If the page also had a line of three dashes further down, Caddy ended the header there, and the text in between disappeared.
    What I changed
    I made it end the header at whichever closing line comes first.
    Why it matters
    Pages with a divider line in the body keep all their text.

    see the code, #8259 (opens in a new tab)

  2. 19 Oct 2026

    The log filter for query strings reads URLs the way the server does

    What was broken
    Caddy can hide secret values in the query string of logged URLs. The filter read the URL differently from the server, so anything after a hash sign slipped past it and was written to the log in plain text.
    What I changed
    I made the filter read the URL the same way the server does, so the whole query is filtered.
    Why it matters
    A token sent in a URL with a stray hash sign no longer leaks into the access logs.

    see the code, #8255 (opens in a new tab)

  3. 19 Oct 2026

    An impossible IP mask is caught when the config loads

    What was broken
    Caddy accepted IP masks in its log filter that cannot exist, and then logged a blank value instead of the client's address.
    What I changed
    I made Caddy reject an out-of-range mask when the config is loaded.
    Why it matters
    A typo in the log settings shows up at startup instead of quietly emptying the client addresses in the logs.

    see the code, #8241 (opens in a new tab)

  4. 16 Oct 2026

    Passwords hashed from a pipe match on Windows line endings

    What was broken
    Piping a password into the hashing command kept the Windows line-ending character as part of the password, so logins with the real password were refused. Input with no final newline failed outright.
    What I changed
    The command now drops a trailing line ending of either kind and accepts input without one.
    Why it matters
    A password hashed from a script or file works for logging in.

    see the code, #8227 (opens in a new tab)

  5. 16 Oct 2026

    Log folders get usable permissions

    What was broken
    With one log permission setting and no file mode, the server created missing log folders that even it could not open, then failed to start.
    What I changed
    Those folders now get permissions that match the log file's default, so the server can write into them.
    Why it matters
    The server starts and writes its logs with that setting.

    see the code, #8225 (opens in a new tab)

  6. 16 Oct 2026

    Each default header is checked on its own

    What was broken
    A settings block can add headers only when a response lacks them. If any one of those headers was already set, every default in the block was skipped, and a condition on the block was ignored for them.
    What I changed
    Each default header now checks only for itself, and the block's condition applies to it.
    Why it matters
    Security headers meant as defaults now get sent.

    see the code, #8217 (opens in a new tab)

  7. 13 Oct 2026

    Redirects from PHP-style apps now actually redirect

    What was broken
    Apps behind the server can answer with just a 'go here instead' address. The server sent that as a normal 'OK' page, so browsers stayed put instead of following the redirect.
    What I changed
    The server now sends it as a redirect, as the standard says and other servers already do. An app that sets its own status still wins.
    Why it matters
    Logins, form submits and other pages that redirect work the way the app meant.

    see the code, #8209 (opens in a new tab)

  8. 13 Oct 2026

    Uploads over the size limit are refused, not cut short

    What was broken
    With unlimited buffering turned on, the server ignored errors while reading a request. An upload over the size limit was cut off and passed on as if complete, and the user got 'OK' instead of 'too large'.
    What I changed
    Read errors now go through the same path as with a buffer limit, so the server reports them instead of hiding them.
    Why it matters
    Apps never receive a half upload that looks whole, and users are told when a file is too big.

    see the code, #8207 (opens in a new tab)

  9. 12 Oct 2026

    Custom error pages now follow the order you wrote them

    What was broken
    A site can set different error pages, like one for 'not found' and a general one for other mistakes. The server checked them in reverse order, so the general page showed up where the 'not found' page should have.
    What I changed
    The server now keeps the order written in the settings file.
    Why it matters
    Visitors see the error page the site owner meant for them.

    see the code, #8195 (opens in a new tab)

  10. 10 Oct 2026

    Pages that exist no longer show 'not found'

    What was broken
    One form of a setting that says 'try this file, then that one, else show not found' gave every page a 'not found' error, even pages that existed.
    What I changed
    Once one rule in a group has matched, the server now skips checking the rest of that group.
    Why it matters
    Sites using that setting serve their real pages again.

    see the code, #8189 (opens in a new tab)

  11. 10 Oct 2026

    A repeated rule line is now an error, not silently ignored

    What was broken
    In the server's settings file, a rule could list two custom conditions. The server quietly used only the first one, so the rule matched more requests than intended.
    What I changed
    The server now refuses that setup and says how to combine the conditions into one.
    Why it matters
    The mistake is caught when the settings load, instead of quietly changing which requests a rule applies to.

    see the code, #8183 (opens in a new tab)

  12. 9 Oct 2026

    Security settings stay on pages that send early hints

    What was broken
    Sites add extra instructions to every reply, like 'always use a secure connection'. If the backend first sent a quick early note (an 'early hint'), those instructions vanished from the final reply.
    What I changed
    I save the site's own instructions before handling the early note and put them back afterwards.
    Why it matters
    Security settings a site asks for now reach browsers every time.

    see the code, #8169 (opens in a new tab)

  13. 9 Oct 2026

    Successful requests are no longer retried into an error

    What was broken
    The server can pass requests to backend servers and retry on failure. A retry rule that checked only the request also retried replies that had succeeded, until the user got an error page.
    What I changed
    Retries based on the reply now happen only when the rule looks at the reply.
    Why it matters
    Requests that succeed the first time are sent once and reach the user, instead of failing.

    see the code, #8168 (opens in a new tab)

  14. 9 Oct 2026

    The server stopped lying about the size of compressed files

    What was broken
    When a program asked only for a file's details, not the file itself, the server reported a wrong size (20 bytes) for compressed files.
    What I changed
    The server still sends the right details, but no longer makes up that false size.
    Why it matters
    Tools that check a file's size before downloading, like download managers and caches, now get the truth.

    see the code, #8150 (opens in a new tab)

  15. 8 Oct 2026

    Page errors no longer send a broken, half-finished reply

    What was broken
    When a page the server fills in before sending (a template) had an error, the error reply still claimed the original file's size but had no content, so it looked cut off.
    What I changed
    On any template error, the server now drops the file's leftover details before sending the error.
    Why it matters
    Visitors and tools get a clean error message instead of a broken reply.

    see the code, #8149 (opens in a new tab)

  16. 7 Oct 2026

    Traffic now goes to the least busy server when all are busy

    What was broken
    One way of sharing traffic should send each request to the less busy of a few backends. Once all of them were busy, it picked at random, even the busiest one.
    What I changed
    I fixed the comparison so only the least busy backends stay in the running.
    Why it matters
    In a test with a slow and a fast backend, the fast one got 70 of 80 requests instead of 41.

    see the code, #8160 (opens in a new tab)

  17. 7 Oct 2026

    No more crash when a backend is down and weights are missing

    What was broken
    The server can share visitors between backends by weight (how much traffic each gets). With fewer weights than backends and one backend down, it crashed and visitors got empty replies.
    What I changed
    Backends without a weight are now treated as getting no traffic, instead of crashing the server.
    Why it matters
    A small gap in the setup no longer breaks the site when one backend goes down.

    see the code, #8159 (opens in a new tab)

← every project