🠰 8.21.0 all changes pending release
Changes in 8.22.0 - September 2 2026
Changes:
- gssapi: add support for Apple GSS Framework
- hardening: add API guards
- RFC 9421 HTTP Message Signatures support
- spnego: block NTLM fallback in SPNEGO negotiation
- TLS: drop support for TLS-SRP
- vquic: add option to use Apple fast UDP
Bugfixes:
- altsvc: continue after unknown parameters
- asyn-thrdd: retry link-local ipv6 if missing scope id
- autotools: minor fixes and improvements
- build: always use local `inet_pton()`/`inet_ntop()` implementations
- build: assume POSIX `select()` is available
- build: clear `Require.private` for static-only builds in `libcurl.pc`
- build: drop `dirent.h` and `opendir()` detections on Windows
- build: drop detecting `gettimeofday()` on Windows
- build: drop superfluous `STDC_HEADERS` macro
- build: enable thread-safe `getaddrinfo()` for OpenBSD
- build: minor debug option message fixes/improvements
- build: require `!NDEBUG` for debug-enabled (aka development) builds
- build: strip duplicate spaces after `Libs.private:` in `libcurl.pc`
- build: strip trailing spaces from `libcurl.pc`
- cd2nroff: fix backslashes for 4-space indent lines
- cd2nroff: stricter checks for asterisks for italics
- cf-ngtcp2-cmn: de-duplicate `ngtcp2_conn_client_new()` call code
- cf-ngtcp2-cmn: initialize new callback ptr for ngtcp2 1.24.0+
- cf-socket: avoid broken NetBSD SOCK_NONBLOCK
- cf-socket: disable TCP SYN retransmissions for localhost on Windows
- cfilters: fix event-based connection shutdown
- clock: save one call
- cmake/FindLibgsasl: fix to set `LIBGSASL_VERSION` with pkg-config detection
- cmake: check libgsasl version at configure time
- cmake: dedupe expressions into local vars in `cmake_uninstall.in.cmake`
- cmake: fix not to build `tunits` when `BUILD_CURL_EXE=OFF`
- cmake: flatten build tree, tidy up base dir variables
- cmake: minor improvements to `cmake_uninstall.in.cmake`
- cmake: optimize OpenSSL fork detection
- cmake: replace `remove` command with `rm` and pass arg safely
- cmake: robustify base path in local file reference
- cmake: stop probing unused `float.h` for `STDC_HEADERS`
- cmake: use built-in variable and target property dump functions with CMake 4.5+
- config-riscos.h: delete handcrafted RISC OS config header, in favor of autotools
- config-win32.h: drop UWP, c-ares, simplify more
- config-win32.h: limit use to MSVC IDE Project builds
- configure: clarify --enable-debug option
- configure: fix misleading error messages
- configure: link `-lcrypt32` instead of `-lm` for wolfSSL on Windows
- configure: only check in the watt library if WATT_ROOT is set
- configure: remove double check for GnuTLS
- configure: set ldap lib to no by default for non-finds
- conncache: apply multi limits to transfers using a shared pool
- conncache: conn upkeep/alive: move and enhance
- conncache: connection alive checks intervals
- conncache: don't assume curl_off_t increment wrap-around
- conncache: guess maxconnects different
- connect: connection close tweaks
- connect: only set connect timer on first socket
- connection reuse: age check
- connection reuse: check SSL configs when doing a scheme upgrade
- connections: use admin handles only for maintenance
- content_encoding: exact-match the identity transfer-coding token
- content_encoding: give a clear error on multi-member gzip
- cookie: cookies set for an exact PSL domain is host-only
- cookie: improve TAB handling
- cookie: refuse to load cookies set against a PSL domain
- CREDENTIALS.md: remove comment about empty user/pass
- ctype: exclude control bytes from ISPRINT and ISGRAPH
- curl: help category cleanups
- curl_gssapi: document/update feature availability
- curl_threads: always use native threads/mutex on Windows
- curl_trc: remove unused expire timers
- curl_url_set.md: expand the CURLU_NO_AUTHORITY description
- curl_ws_meta.md: polish and better vocabulary
- CURLOPT_HEADERFUNCTION.md: document folded header unfolding
- CURLOPT_SOCKOPTFUNCTION.md: ALREADY_CONNECTED does not work for HTTP/3
- CURLOPT_SSH_*_KEYFILE: used for setting up, then no more
- CURLOPT_UNRESTRICTED_AUTH.md: 'Authorization', not 'Authentication'
- CURLOPT_USERNAME.md: ambient username caveats
- CURLSHOPT_(UN)SHARE.md: do not modify shares while in use
- curlx_inet_ntop: return `CURLcode`, drop setting `errno`
- curlx_inet_pton: drop setting `errno` on error
- DEPRECATE.md: HTTP/2 Server Push gets removed in March 2027
- dict: avoid busy-loop in sendf() when the socket is not writable
- dist: fix to drop test bundle .c files from the source tarball
- dnsd: fix bounds check in `read_https_alpn_part()`
- docs/INTERNALS.md -> docs/DEPENDENCIES.md
- docs: clarify that cookies need domain set to match
- docs: connection reuse behavior for socket callbacks
- docs: make 5 example snippets compile cleanly with clang
- docs: mention possible auth option conflicts
- docs: remove doubled word in SECURITY-ADVISORY.md
- DoH: improvements
- easy: fix unused global on non-Windows
- easy_lock: silence `portability-no-assembler` with clang-tidy 23.1.0+
- FAQ: correct an option typo
- file: support directory listing on Windows
- filter: change time reporting
- FTP: fix TLS session reuse on the data connection
- ftp: reject control bytes in ACCT and alternative-to-user
- gitignore: maintenance updates
- gopher: fix partial sends of CRLF
- gopher: reject CR and LF in the selector
- h2 push: use squeaky clean easy handle
- h2: bootstrap max streams from multi handle if in use
- h3-proxy: fix NULL deref when non-:status header arrives before :status
- Happy Eyeballing v3: resolution delay of 25ms
- header api: add guards
- headers: name the arguments the way the definitions name them
- HISTORY.md: PSL support in 2015
- HISTORY: add when c-ares support was introduced (2004)
- HISTORY: September 1999: started using CVS
- hostip: only cache negative resolves for authoritative answers
- hsts: only match the exact strings
- http digest: tie peer/credentials on input
- http2: make server push transfers inherit share from parent
- http2: remove assert in ingress processing
- http: avoid length underflow in Curl_compareheader
- http: custom Authorization: header overrides Negotiate
- http: fix non-tunneling proxy hostname use
- http: stop dropping large custom headers
- http: trim custom header name before the Authorization drop
- httpsrr: DoH with HTTPS, fix response handling
- idn: restore `MultiByteToWideChar()` `MB_ERR_INVALID_CHARS` flag
- imap: APPEND CRLF fix
- include: include <sys/select.h> when building for modern Linux.
- INSTALL.md: add building-from-source overview section
- INTERNALS.md: require quiche 0.20.0+
- ipv6 scope_id: set from first peer
- keylog: add a random size argument to Curl_tls_keylog_write()
- ldap: base64-encode LDIF values beginning with colon or less-than
- ldap: reject control characters in URL-decoded filter values
- ldap: support empty username and password
- ldap: support insecure mode for Windows native LDAP
- lib1587: fix gcc `-Wconversion` with LibreSSL on Windows, test in CI
- lib2405: adjust for non-threaded builds
- lib: add "Curl_" prefix to two global functions
- lib: add multi_wakeup_internal
- lib: drop unused `system_win32.h` includes
- lib: fix 'ns' -> 'us' in trace messages
- lib: new easy option string storage
- lib: optimize struct layouts for reduced memory usage
- lib: ratelimit timestamps
- lib: silence gcc-16 compiler warnings `-Wmaybe-uninitialized`
- lib: update mentions of the legacy "sessionhandle"
- libcurl.md: emphasize that the output needs checking
- libcurl.pc: add `License` tag
- libcurl.pc: add Copyright tag to the pkgconf file
- libcurl.pc: add the Link.ABI and Source tags
- macos sectrust: fail ocsp verify when not builtin
- Makefile.am: improve etags
- mbedtls: enforce verifyhost when verifypeer is disabled
- mbedtls: replace `memset()` with `psa_hash_operation_init()`
- md5: replace magic numbers with `MD5_DIGEST_LEN`
- mime.c: avoid integer overflow in base64 size calculation
- mime: reject CR and LF in mail part name and filename
- mod_curltest: fix compiler warnings
- mprintf: acknowledge %F
- mprintf: avoid never-ending loop for positive-infinite
- mprintf: fix long double output
- mqtt: reject control bytes in the topic
- multi: cap expire times to INT_MAX internally
- multi: forbid curl_easy_pause from within multi socket callback
- multi: hold timeout values in 'int' instead of 'long'
- multi: remove #if 0'ed code that uses old struct
- multi: shrink expire timer indices
- multi: timeout improvements
- multi: use index list for expire timeouts
- multi: xfer table initial size and growth
- multihandle: move two struct fields
- ngtcp2+openssL: fix early data
- ngtcp2: avoid NULL deref in cf_ngtcp2_send
- ngtcp2: clean up after ngtcp2 in `curl_global_cleanup`
- ngtcp2: let verify failures win over expiry processing errors
- openldap: handle Curl_sasl_continue() returns better
- openssl+sectrust: fix session reuse
- openssl+sectrust: move session verified set into result check
- openssl: avoid conn reuse if provider is used
- openssl: avoid strlen() on the data from OpenSSL
- openssl: aws-lc ocsp workaround
- openssl: drop unused pre-OpenSSL3 `ctx_option_t` typedef
- openssl: fix DER buffer leak in Apple SecTrust verification
- openssl: no server cert is only okay if also not pinned
- openssl: prefer modern API flavors for `EVP_MD_CTX` new/free
- openssl: replace stray legacy API variant with `EVP_DigestInit_ex()`
- os400: port latest header files changes to ILE/RPG interface
- os400: rewrite upper ebcdic wrappers using dynbuf
- progress: cleanup, less memory
- protocol: simpler Curl_getn_scheme runs faster
- proxy: CONNECT trailers handling
- psl: update a comment to understandable English
- pytest: update two H3 tests for nghttp3 1.18.0+
- quic: upload improvements
- quiche: set the max field section size
- rtsp: refactor method handling and improve error checks
- runtests: allow comments in `setenv` section, merge sections in test433
- runtests: fix `mode="warn"` tests passing unconditionally, fix test 1752
- runtests: flush cached test parts when (re)loading a file
- runtests: restore `-k` option and actively process as no-op
- sasl: fix zero-length response encoding
- schannel: add ALPN support for mingw-w64 <9 and <VS2015
- schannel: clear PFX password before free
- schannel: fix ALPN erroneously disabled
- schannel: fix error check logic in `get_client_cert()` file reader
- schannel: refresh stream sizes after renegotiation
- schannel: reuse the send buffer
- schannel: shut off experimental TLS 1.3 support for Win 10
- scorecard: fix `max_upload` init value in `ul_parallel()`
- scripts/badwords.txt: do not recommend using 'will' in rewrites
- scripts: replace/extend `--` with `--end-of-options` in git commands
- scripts: use end-of-options marker in `cd`, `mkdir`, `mv`, `sha256sum` commands
- servers: fix HANDLE leak in UWP builds
- servers: fix to reverse `SA_RESTART` option for `sigaction()` on modern codepath
- setopt: allow setting a referer from CURLINFO_REFERER
- setopt: error for CURLOPT_SHARE when easy handle is used
- setopt: make NULL `CURLOPT_AWS_SIGV4` disable aws-sigv4 auth
- setopt: return OK earlier for the deprecated h2 dep options
- share unlink: forget connection
- smtp: reject CR and LF in the envelope address
- spacecheck: cap number of lines per file
- spnego_sspi: drop redundant UNICODE branch
- spnego_sspi: pass channel bindings on initial context
- src: safely clear certain buffers
- sshserver.pl: bump an sshd config to use its modern name
- ssls: fix potential memory leak on import
- sspi: add local helper macro to avoid UNICODE branching
- sspi: enable channel-binding in mingw-w64 <9 builds
- strcase: inline the raw case conversions
- sws: allow connection-monitor to log all disconnects
- sws: log the exact closing reason better, to help debugging tests
- terminal: Enhance terminal size detection for multiple outputs
- test 1560: test RFC4291 style IPv6 IPv4-mapped addresses
- test1560: allow to build and run without LDAP support
- test798: force IPv4 to avoid cross-runner port aliasing
- test: adjust test_06_13 for 0100::/64 being blackholed
- tests: address mutable class vars and naive datetime in Python code
- tests: change whitespace and comments in Python test code
- tests: convert unit test 1396 and 1398 into libtests
- tests: enable and fix some new Python ruff warnings
- tests: fix Content-Length mismatch in test 2064
- tests: fix the FTP check for unexpected RST
- tests: fix type promotion on 32-bit arches in http test code
- tests: fix typo in assert message in http test
- tests: improve exception handling in Python test code
- tests: remove test1701
- tests: simplify by removing unneeded Python code
- tests: skip test 311 for wolfSSL 5.9.2
- tests: target Python 3.8 as the minimum Python version
- tests: use simpler constructions in Python code
- thrdpool: retry failed thread starts while items wait
- thrdqueue: drop name strdups from Curl_thrdq_create
- tidy-up: `TEXT()` vs `_TEXT()` vs `_T()` use (Windows)
- tidy-up: comments, messages, formatting
- tidy-up: drop redundant includes
- tidy-up: fix Perl syntax and formatting nits
- tidy-up: fix typos in docs and comments
- tidy-up: formatting, messages and comments
- tidy-up: minor code fixes and improvements
- tidy-up: typos, comment nits
- timeval: make `Curl_freq` variable static (Windows)
- tool: checkfds, open on null device
- tool: do not flush on out-null
- tool: fix memory use in parallel mode
- tool: init progress bar on demand
- tool: remove duplicate setopts
- tool_cb_hdr: de-duplicate filename setter
- tool_cb_hdr: do not truncate etags output to stdout
- tool_cb_prg: avoid integer overflows
- tool_doswin: add stdin relay auth
- tool_doswin: don't use `TerminateThread` in stdin relay
- tool_doswin: fix stdin data truncation
- tool_msgs: make notef() respect --silent
- tool_operate: limit `is_using_schannel()` call to Windows
- tool_operate: only check for schannel if on windows
- tool_operate: remove call to abort()
- tool_paramhlp: --proto only supports one modifier
- tool_xattr: add support for Windows alternate data stream
- transfer: DID handling
- typecheck-gcc: allow passing `char[]` as callback data
- uint-spbset: reused empty chunks
- unit3214: fix to pass on systems with >=128-bit pointers
- url: fix handling of empty user in NTLM matching
- url: fix negotiate/ntlm connection reuse
- url: reject control codes in credentials set via CURLOPT
- urlapi: allow URLs to not have userauth (hostname)
- urlapi: avoid dedotdotify() if possible
- urlapi: clear password buffer on error path
- urlapi: do not keep an internal port string
- urlapi: improved return codes
- urlapi: preserve empty markers in relative URLs
- urldata: cleanups
- urldata: drop four strings from the aptr struct
- urldata: sort the connectdata struct fields by size
- VERSIONS.md: document Rock-solid curl releases
- vms: fix symbol typo and missing closing quotes in `config_h.com`
- vquic: add Curl_ prefix to some global functions
- vquic: initialize new callback slot for nghttp3 v1.18.0+
- vquic: silence `-Wmissing-field-initializers` for nghttp3/ngtcp2 callback tables
- vquic: use ngtcp2 v1.25.0 new close2 callback
- vssh: keyfile use cleanups
- vssh: silence gcc-11 `-Wnull-dereference`, dedupe `CURL_EASY_STR()` calls
- vtls: move 'native_ca_store' ssl_config_data => ssl_primary_config
- vtls_scache: use case sensitive path match
- VULN-DISCLOSURE-POLICY.md: issues that should be found by tests are LOW
- wcurl: import v2026.08.30
- websocket: pause writing and meta data fix
- winsock: drop redundant version checks at initialization
- wolfssl: do not run Curl_wssl_setup_x509_store() twice
- wolfssl: fix build for wolfssl without bio chain support
- ws: fix write callback error handling
- ws: pause/unpause write handling