Skip to content

Update reqwest from 0.12 to 0.13 - #1018

Open
schneems wants to merge 1 commit into
mainfrom
schneems/fix-dependency
Open

schneems wants to merge 1 commit into
mainfrom
schneems/fix-dependency

Conversation

@schneems

Copy link
Copy Markdown
Contributor

The reqwest crate 0.13 removes the rustls-tls-native-roots feature and defaults the rustls backend to rustls-platform-verifier for root certificates. On macOS and Windows that verifier uses the operating system trust store and ignores SSL_CERT_FILE, which is a feature we explicitly need and test for.

This change loads the native root certs with rustls-native-certs and passes them to reqwest through tls_certs_only to keep that support on every platform. reqwest 0.12 pulled in rustls-native-certs behind the removed feature, so this declares it directly.

close #979

The reqwest crate `0.13` removes the `rustls-tls-native-roots` feature and defaults the rustls backend to `rustls-platform-verifier` for root certificates. On macOS and Windows that verifier uses the operating system trust store and ignores `SSL_CERT_FILE`, which is a feature we explicitly need and test for.

This change loads the native root certs with `rustls-native-certs` and passes them to reqwest through `tls_certs_only` to keep that support on every platform. reqwest 0.12 pulled in `rustls-native-certs` behind the removed feature, so this declares it directly.

close #979
@schneems
schneems marked this pull request as ready for review September 30, 2026 13:18
@schneems
schneems requested a review from a team as a code owner September 30, 2026 13:18
@schneems
schneems requested a review from edmorley September 30, 2026 13:18

@edmorley edmorley left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking this might be a quick approve, however, Claude found some issues, and also the premise (macOS and Windows support) isn't something we need for buildpacks. So I'm not sure this is the best approach? The backend situation for reqwest is a bit complicated - I'd need to sit down and take a closer look to say any more.


Summary from Claude:

I don't think we need the rustls-native-certs workaround, and as written it causes a regression:

  1. One unparseable cert in the store breaks every download. With only the rustls backend enabled, reqwest::Certificate::from_der never fails (it just copies the bytes), so the .filter_map(... .ok()) filters nothing. tls_certs_only then adds each root with RootCertStore::add(..)?, so a single cert rustls can't parse makes build() fail. reqwest 0.12 skipped such certs on purpose, and so does rustls-platform-verifier. To reproduce on Linux, use an SSL_CERT_FILE bundle containing the badssl cert plus one junk CERTIFICATE block. That passes on main but fails on this branch with reqwest::Error { kind: Builder, source: InvalidCertificate(BadEncoding) }.
  2. On Linux, reqwest 0.13's default verifier already honours SSL_CERT_FILE. There, rustls-platform-verifier calls rustls_native_certs::load_native_certs() itself (source). Only macOS and Windows use the OS trust store instead, and buildpacks (and our CI) only run on Linux. So dropping tls_certs_only and rustls-native-certs keeps the 0.12 behaviour where it matters. test_self_signed_certificate would then just need #[cfg(target_os = "linux")].

An alternative worth considering is switching download to ureq 3 with default-features = false, features = ["rustls", "platform-verifier"]. It uses ring by default without any global state, and the download dependency tree drops from 95 crates to 38 (no tokio, hyper or aws-lc). We already use it in libcnb-test and most of our buildpacks. On Linux it behaves the same, including in the bad-cert case.

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.

2 participants