Problem
When running confluence2md against a Confluence instance whose TLS certificate is signed by a corporate / internal Certificate Authority, the tool fails with:
Error: HTTP request failed: https://<internal-confluence>/rest/api/content/...:
client error (Connect): invalid peer certificate: UnknownIssuer
The corporate root CA is present in the Windows certificate store (verified), but confluence2md does not see it.
Root cause
Cargo.toml declares:
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"] }
The rustls-tls feature bundles Mozilla's WebPKI root CA store at compile time (via webpki-roots). It never consults the OS certificate store (Windows CryptoAPI / macOS Keychain / Linux NSS). Corporate / self-signed CAs that exist only in the system store are therefore unknown to rustls and the TLS handshake fails.
Environment
- OS: Windows 11 (corporate environment)
confluence2md version: 2.3.1
- Confluence server certificate issuer:
CN=XXX, O=XXX
- CA present in Windows certificate store: yes
- Standard env vars tried (
SSL_CERT_FILE, CURL_CA_BUNDLE, REQUESTS_CA_BUNDLE): no effect (none are supported by rustls)
Suggested fix
Replace the rustls-tls feature with rustls-tls-native-roots, which uses rustls-native-certs to load root CAs from the OS store at runtime:
# Cargo.toml
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-native-roots"] }
This is a one-line change and makes the tool work out-of-the-box in corporate environments without any user configuration.
Alternatively, a --ca-bundle <path> CLI option (and matching CONFLUENCE2MD_CA_BUNDLE env var) would let users point to a custom PEM CA bundle — useful for environments where the native cert store is not straightforward to access.
Workaround
As a temporary workaround, we extracted the corporate CA chain from the Windows store into a PEM bundle and wrote a Python wrapper that passes it via ssl.create_default_context(cafile=...). The page converts successfully this way, confirming the issue is purely the CA trust store.
References
Problem
When running
confluence2mdagainst a Confluence instance whose TLS certificate is signed by a corporate / internal Certificate Authority, the tool fails with:The corporate root CA is present in the Windows certificate store (verified), but
confluence2mddoes not see it.Root cause
Cargo.tomldeclares:The
rustls-tlsfeature bundles Mozilla's WebPKI root CA store at compile time (viawebpki-roots). It never consults the OS certificate store (Windows CryptoAPI / macOS Keychain / Linux NSS). Corporate / self-signed CAs that exist only in the system store are therefore unknown torustlsand the TLS handshake fails.Environment
confluence2mdversion: 2.3.1CN=XXX, O=XXXSSL_CERT_FILE,CURL_CA_BUNDLE,REQUESTS_CA_BUNDLE): no effect (none are supported byrustls)Suggested fix
Replace the
rustls-tlsfeature withrustls-tls-native-roots, which usesrustls-native-certsto load root CAs from the OS store at runtime:This is a one-line change and makes the tool work out-of-the-box in corporate environments without any user configuration.
Alternatively, a
--ca-bundle <path>CLI option (and matchingCONFLUENCE2MD_CA_BUNDLEenv var) would let users point to a custom PEM CA bundle — useful for environments where the native cert store is not straightforward to access.Workaround
As a temporary workaround, we extracted the corporate CA chain from the Windows store into a PEM bundle and wrote a Python wrapper that passes it via
ssl.create_default_context(cafile=...). The page converts successfully this way, confirming the issue is purely the CA trust store.References
rustls-tls-native-rootsin reqwest docsrustls-native-certs