🠰 8.20.0 all changes pending release
Changes in 8.21.0 - June 24 2026
Changes:
- curl: named globs in output filename for upload glob references
- HTTP/3: add proxy CONNECT and MASQUE CONNECT-UDP support (ngtcp2 QUIC)
- http2: remove stream dependency tracking
- lib: drop support for CURLAUTH_DIGEST_IE
- libssh: add support for SHA256 host public keys
- tool_urlglob: add named globs
Bugfixes:
- _ENVIRONMENT.md. Windows does case insensitive env variables
- _URL.md: remove the zone-id mention
- AmigaOS: curl_setup.h avoid explicit_bzero with clib2
- AmigaOS: fix build fallouts, re-add to CI
- asyn-thrdd: add IPv6 guards
- asyn-thrdd: fix result processing without wakeup socketpair
- autotools: mbedtls detection fixes
- BINDINGS: Update Hollywood link
- BUFQ.md: re-sync with source code
- build: enable `-Wlogical-op` picky warning for GCC 4.4+
- build: omit zlib pkg-config reference for Android
- cf-h2-prox: fix peer leak
- cf-h2-proxy: drop interim responses
- cf-https-connect: do not engage on proxy origin
- cf-ip-happy.c: minor comment typo
- cf-ip-happy: update documentation
- cf-socket: make Curl_addr2string static
- cf-socket: set scope_id for IPv6 link-local addresses
- cf-socket: store errno from do_connect in ctx->error
- cfilters: fix busy loop on blocked transfers
- chunked: reject invalid bytes in trailer
- CIPHERS.md: fix the example that uses only TLS 1.3
- cmake/FindGSS: drop "MIT Unknown" version value, related tidy ups
- cmake/FindGSS: drop CMake <3.16 compatibility logic
- cmake/FindGSS: fix comment, adjust custom flavor property name
- cmake/FindGSS: prioritize MIT over GNU in pkg-config detection
- cmake: auto-select static nghttp2/nghttp3/ngtcp2 Config
- cmake: export/forward `NGTCP2_CRYPTO_BACKEND`
- cmake: fix three issues generating lib options in config files
- cmake: fix zstd CMake config name
- cmake: opt in `MSVC_VERSION` 1951 to picky warnings
- cmake: quote `COMPONENTS` string in `curl-config.in.cmake`
- cmake: simplify `LINK_ONLY` imported target extraction
- config2setopts: use default protocol properly
- connect: remove deref of freed pointer in trace call
- content_encoding: fix limit failure message
- content_encoding: fix non-last chunked rejection
- content_encoding: timeout during slow decoding
- cookie: check __Secure- and __Host- case sensitively when read from file
- cookie: compare path case sensitively
- cookie: reject control octets in file-loaded cookies
- cookie: simplify strstore(), remove outdated comment
- cookie: tailmatch the domains for secure override
- cookie: trim trailing dots when checking PSL
- creds: add sasl service name
- creds: create with empty user+pass
- creds: mask OAuth bearer token in trace logs
- creds: remove two unused functions
- curl_easy_pause.md: rephrase the stream cache when pause clause
- curl_easy_setopt.md: change options when no transfer runs
- curl_formdata: fix to pass long where missing, document `CURLFORM_NAMELENGTH`
- curl_multi_assign.md: clarify lifetime
- curl_ntlm_core: fix nettle 4+ builds in certain MultiSSL combos
- curl_ntlm_core: propagate DES `CryptEncrypt()` error
- curl_sha512_256: fix result code on error
- CURLINFO_CONTENT_LENGTH_UPLOAD_T.md: expand
- CURLMOPT_SOCKETFUNCTION.md: this sends *all* file descriptors
- CURLOPT_CHUNK_BGN_FUNCTION: target is there for symlinks only
- CURLOPT_DISALLOW_USERNAME_IN_URL: is for CURLOPT_URL only
- CURLOPT_DOH_URL.md: does not inherit proxy options
- CURLOPT_ECH.md: simplify the description language
- CURLOPT_HAPROXYPROTOCOL.md: only sent for newly setup connections
- CURLOPT_MAXFILESIZE: clarify this also works for on-going transfers
- CURLOPT_PINNEDPUBLICKEY.md: does not apply for other origins
- CURLOPT_PORT.md: use stronger language
- CURLOPT_SHARE: warn about early remove
- CURLOPT_SSH_HOSTKEYFUNCTION.md: for new connections only
- CURLOPT_WRITEFUNCTION.md: mention redirects
- CURLOPT_WRITEFUNCTION.md: remove stray reference to HSTS
- delta: harden external command invocations
- digest: escape control codes too
- digest: flush proxy state on proxy or credential change
- digest: flush state on origin or credential change
- dns-httpsrr-lookup: use origin, not peer
- dnscache: remove Curl_dns_entry_link
- docs/libcurl: fix the version for curl_multi_socket_action
- docs: end "...can be used several times..." sentences with period
- docs: fix --follow doc typo
- docs: fix a couple of typos
- docs: fix grammar and wording in FAQ
- docs: fix odd wording in CONTRIBUTE.md
- docs: note CURLOPT_PINNEDPUBLICKEY has no effect on legacy LDAP backend
- docs: returned header size reflects HTTP/1-style format
- doh: cap the maximum TTL to 24 hours
- doh: stricter HTTPS RNAME parsing
- ECH: cleanups
- event: fix wakeup consumption
- ftp: avoid accessing EPSV response one byte past the NULL
- ftp: remove 2 Curl_resolv_blocking() calls
- ftp: remove bits.ftp_use_control_ssl
- ftplistparser: clear strings.target if not symlink
- gnutls: allow building with nettle 4.0
- gnutls: fix more nettle 4+ compatibility issues
- gnutls: require 3.7.2 for earlydata
- gsasl: fix potential double free
- gtls: fix ignored return and uninitialized status in OCSP check
- gtls: fix some typos
- gtls: minor fixes and improvements
- gtls: use the correct return code in trace output
- gtls: verify OCSP response signature in gtls_verify_ocsp_status
- h3-proxy: fix callback return values, and a typo in tests
- hostip: remove unused MAX_HOSTCACHE_LEN and MAX_DNS_CACHE_SIZE
- hsts.md: mention multiple curl invokes effect
- hsts: duplicate live HSTS data in curl_easy_duphandle
- http-proxy: verify CONNECT response headers
- HTTP3.md: update quiche build
- http: don't pass on set cookies to new origins
- http: prefer chunked encoding over Content-Length: 0
- http: reject spurious CR bytes in headers
- http_digest: return better error
- idn: replace header guards with forward declaration
- INSTALL-CMAKE.md: document CMake environment variables
- INTERNALS.md: document minimum nghttp3 and ngtcp2 versions
- KNOWN_BUGS.md: remove fixed GnuTLS <-> OpenSSL incompat bug
- KNOWN_BUGS: remove stale Threads::Threads entry
- krb5_sspi: fix error message on `DecryptMessage()` fail
- ldap: base64 encode binary LDIF values with WinLDAP
- ldap: fix minor leak on write callback error
- ldap: fix to not leak `attribute` on OOM (WinLDAP)
- ldap: switch off chasing referrals
- lib678: fix to not be perma-skipped
- lib: make `__STDC_VERSION__` literals `L` (where missing)
- lib: transfer origin and proxy handling
- lib: two minor typos
- libcurl-easy.md: minor clarifications
- libssh2: do not use deprecated macros when unavailable
- libssh2: drop stray double-negative from `strncmp()` result
- libssh2: fix to return error code on missing parameter
- libssh2: replace macro names with non-misspelled alternatives
- libssh2: save non-standard port to `known_hosts`
- libssh2: sync version check with INTERNALS.md
- libssh2: use non-deprecated `libssh2_knownhost_addc()`
- libssh: map SSH_KNOWN_HOSTS_OTHER to CURLKHMATCH_MISMATCH
- m4: drop redundant conditions in TLS library detections
- Makefile.am: drop test1190 listed twice
- managen: apply minor fixes and improvements
- mbedtls: null-terminate the private key blob
- mk-unity.pl: `#include`, and not concatenate input headers
- mqtt: return error on truncated Remaining Length
- mqtt: validate PINGRESP and DISCONNECT have remaining_length == 0
- multi: handle pause in multi socket callback
- multi: remove a stale comment
- multi: silence gcc 16 `-Wnull-dereference`, bump CI job to test
- multi: xfers_really_alive
- netrc: remember and check filename loaded
- netrc: scanner refactor
- ngtcp2: fail handshake directly
- openssl: do not mix OpenSSL int result with `CURLcode` variable
- os400sys: fix theoretical length overflows
- peer.h: fix typo in comment
- pingpong: reject nul byte in server response line
- progress: fix CURLINFO time reporting
- psl: require libpsl 0.16.0 (2016-12-10) or greater
- pytest: pass `--disable` to curl
- pytest: re-enable test test_05_01 and test_05_02 for quiche 0.29.0+
- pythonlint.sh: make it fail on error, fix ruff warnings in pytest
- quic: count zero length packets against max
- ratelimits: use minimal burst rate
- RELEASE-PROCEDURE.md: update coming release dates
- resolve: mention in error that IP address is expected
- rtsp: bump buf after rtsp_filter_rtp()
- runner.pm: apply minor correctness fix
- runner.pm: set `CURL_TESTNUM` for `precheck` commands
- runtests: fix tests for curl builds with embedded CA bundle
- rustls: error on CURLOPT_CRLFILE with native CA store
- schannel: check `schannel_sha256sum()` success, and more
- schannel: enforce Extended Key Usage for custom CA roots
- schannel: error on TLS 1.3-only with cipher list
- schannel: fix https proxy for client cert and certinfo
- schannel: fix revoke_best_effort setting for proxy
- schannel: use fopen instead CreateFile
- schannel_verify: avoid out of blob access
- schannel_verify: simplify CryptQueryObject use
- scripts: catch Credits-to contributors
- SECURITY-ADVISORY.md: expand
- setopt: changing the proxy port is also a proxy change
- setopt: clear proxy auth properly on NULL
- setopt: clear the "custom" CA booleans when set to NULL
- setopt: CURLOPT_MAXCONNECTS set to 0 restores default value
- setopt: defref the old referer when setting a new
- setopt: fix to honor `CURLOPT_PROXY_CAINFO_BLOB` over Native CA
- setopt: gate a few proxy TLS options by checking backend support
- setopt: more careful cleanup of the HSTS cache
- setopt: return error if received `curl_blob->data` is NULL
- show-headers.md: mention bold headers and --no-styled-output
- sigv4: URL encode the username in the header
- smb: constify `strchr()` result variable
- smb: integer overflow proof a size check
- smbserver: update internal id generation for Python 3
- socket: introduce `SOCK_EAGAIN()` and use it
- socket: use name `sockerr` for socket error variables
- socks_sspi: invalid response length is a fatal error
- socks_sspi: store socks5_gssapi_enctype
- spnego_sspi: honor CURLOPT_GSSAPI_DELEGATION for Windows SSPI
- spnego_sspi: preserve distinction btw policy-only and uncond delegation
- src: fix comment typos
- src: sync nghttp2 versions checks with current requirements
- ssl native_ca_store: always reinit
- SSLCERTS: document 8.19.0 default Native CA builds (Windows)
- sspi: clear SSPI credentials on AcquireCredentialsHandle failure
- sspi: free libcurl allocated memory with curlx_free
- telnet: drop an `int` cast no longer necessary
- telnet: drop redundant interim variables
- telnet: fix error message typos
- telnet: fix old copy-paste typo in variable name
- telnet: honor CURLOPT_TIMEOUT in send_telnet_data()
- test1588: use %TESTNUMBER, not hard-coded number
- test1981: explicitly set the locale
- tests: add `cookies` feature to some tests
- tests: add an assert to avoid IPC blocking
- tests: add the "--resolve" keyword to tests that lack it
- tests: fix unit1636 with --disable-progress-meter
- tftp: avoid the timeout calc if the timeout is crazy
- tftp: stricter option name checks
- tidy-up: add space around operators, where missing
- tidy-up: apply clang-format fixes
- tidy-up: drop stray casts for allocated pointers
- tidy-up: miscellaneous
- tls: fix incomplete mTLS config in conn reuse and session cache
- tls: wolfssl: fixes for PQC key shares
- tool: warn when --ssl and --ftp-ssl-control override each other
- tool_formparse.c: fix two minor comment typos
- tool_formparse: polish error message + make two functions static
- tool_formparse: tool2curlparts is no longer recursive
- tool_help: rectify a bad assert
- tool_operhlp: avoid NULL to %s
- tool_urlglob: avoid overflow at end of range
- tool_urlglob: better 'Duplicate glob name' position
- tool_urlglob: make globbing error reported for correct position
- tool_writeout: fix %time{} output for %s
- transfer: clear referer when set to NULL
- unit1675: fix potential memory leak on dynbuf fail path
- unix-sockets: ignore proxy settings
- URL-SYNTAX: document more URL parsing details
- url: compare full origin when setting credentials
- url: connection credentials origin
- url: connection reuse fixes for starttls
- url: detect proxy changes read from environment
- url: don't log bits.close state
- url: fix connection reuse for starttls protocols
- url: keep the question mark for empty queries
- url: remove superfluous check
- url: url_match_destination fix
- urlapi: accept 0X prefix in IPv4 address as well
- urlapi: change more lowercase percent-encoded to uppercase
- urlapi: compare zone-id in Curl_url_same_origin()
- urlapi: consume trailing dots after IPv4 numerical addresses
- urlapi: deny hostnames with more than one trailing dot
- urlapi: drop base fragment on empty redirect
- urlapi: fix an issue parsing file URLs
- urlapi: fix memleaks on error in `parse_hostname_login()`
- urlapi: fix redirect handling if CURLU_NO_GUESS_SCHEME is set
- urlapi: forbid '|' in host
- urlapi: handle redirect without set scheme with default-scheme
- urlapi: URL decode hostname before IP address normalization
- user-agent.md: mention double quotes too
- var: use a dedicated pointer for the alloc
- verify-release: verify more thoroughly with git
- vquic: drop stray casts for `iovec.iov_len`
- vtls: more large buffer support and error checks for SHA-256
- vtls: use Curl_safecmp for CRLfile and pinned_key comparison
- vtls_scache: include signature_algorithms in the SSL peer cache key
- vtls_spack: drop redundant macro fallbacks
- VULN-DISCLOSURE-POLICY.md: emphasize comm as a human
- VULN-DISCLOSURE-POLICY.md: emphasize the no email thank you part
- VULN-DISCLOSURE-POLICY.md: test code is not secure
- VULN-DISCLOSURE-POLICY: non-released code
- websockets: auto-tunnel through http proxy
- websockets: buffer upgrade data at connection level
- windows: update MS SDK versions in comments
- winldap: avoid NULL pointer deref on `ldap_get_dn()` fail
- ws: make pong sending lazy
- x509asn1: fix DH public key parameter extraction
- x509asn1: fix operator order in do_pubkey