#31098

net.mbedtls: TLS certificate validation fails without an explicit CA bundle, unlike OpenSSL

Opennepinhumopened 6d ago

Describe the bug

With the default mbedTLS backend, http.fetch(validate: true) fails for HTTPS servers with publicly trusted certificates unless verify explicitly names a CA file. The mbedTLS client doesn't automatically load the system's trusted certificate authorities. Thus, the TLS handshake fails with MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED.

The OpenSSL backend (-d use_openssl) handles the same request successfully. When validation is enabled and verify is empty, it calls SSL_CTX_set_default_verify_paths to load the system's trusted roots (vlib/net/openssl/ssl_connection.c.v).

The mbedTLS backend only loads trusted certificates when verify is explicitly provided (vlib/net/mbedtls/ssl_connection.c.v, SSLConn.init). Otherwise, it configures MBEDTLS_SSL_VERIFY_REQUIRED without setting a CA chain.

As a result, HTTPS certificate validation is impossible on the default backend without manually locating and supplying a CA bundle. Applications must either provide their own trust anchors or disable certificate validation.

Reproduction Steps

main.v

import net.http

fn main() {
	r := http.fetch(url: 'https://example.com/', validate: true) or {
		println('failed: ${err}')
		return
	}
	println('status ${r.status_code}')
}

Run with both backends:

  • v run main.v
  • v -d use_openssl run main.v

Expected Behavior

Both backends successfully validate the server certificate against trusted system certificate authorities and print: status 200

When validate: true and verify is empty, the TLS client should use the system's trusted certificate authorities as the OpenSSL backend already does.

If no trusted authorities are available, validation should fail with a clear error rather than silently disabling certificate verification.

Current Behavior

$ v run main.v
failed: net.mbedtls SSLConn.dial, mbedtls_ssl_handshake failed 3; ret: -30336

$ v -d use_openssl run main.v
status 200

The error code -30336 (-0x7680) corresponds to MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED, indicating that no CA chain has been configured.

Possible Solution

No response

Additional Information/Context

No response

V version

V 0.5.2 c4e254f

Environment details (OS name and version, etc.)

V full versionV 0.5.2 c4e254f
OSlinux, "EndeavourOS Linux"
Processor8 cpus, 64bit, little endian, Intel(R) Core(TM) i5-10300H CPU @ 2.50GHz
Memory0.4GB/7.62GB
V executable/home/scher/v/v
V last modified time2026-10-24 13:52:34
V home dirOK, value: /home/scher/v
V vlib dirOK, value: /home/scher/v/vlib
V vlib commitOK, value: c4e254f
VMODULESOK, value: /home/scher/.vmodules
VTMPOK, value: /tmp/v_1000
Current working dirOK, value: /home/scher/projects/vlang/vedrock
Git versiongit version 2.56.0
V git statusweekly.2026.41-958-gc4e254fa (2 commit(s) behind V master)
.git/config presenttrue
cc versioncc (GCC) 16.2.1 20260810
gcc versiongcc (GCC) 16.2.1 20260810
clang versionclang version 23.1.1
tcc versiontcc version 0.9.28rc 2026-07-24 HEAD@85ba3ae8 (x86_64 Linux)
tcc git statusthirdparty-linux-amd64 d6e7ac1b
emcc versionN/A
glibc versionldd (GNU libc) 2.44

Activity

0

No activity yet.