2026-08-17
The asker has an ESP32 DevKitC running Zephyr RTOS. Wi-Fi association works, DNS resolves, and a TCP socket to jsonplaceholder.typicode.com:443 is opened — but when the TLS handshake begins, connect() returns error -116, which is ETIMEDOUT in Zephyr's errno mapping. No TLS alert, no certificate error — just silence, then a timeout.
Why this is interesting: -116 on a TLS socket in Zephyr almost never means "the server didn't answer." The TCP layer clearly worked (they "reach the HTTPS connection stage"), so the handshake bytes are getting somewhere. The timeout is the mbedTLS state machine giving up because it never received a satisfactory ServerHello — or, more commonly, because it never sent a valid ClientHello in the first place. On resource-constrained ESP32 builds with Zephyr's mbedTLS port, several silent misconfigurations produce exactly this symptom.
Likely root causes, in order of probability:
SOCK_STREAM with IPPROTO_TLS_1_2, but tls_credential_add(TLS_CREDENTIAL_CA_CERTIFICATE, ...) was never called, or the sec_tag_list passed via setsockopt(TLS_SEC_TAGS) is empty. mbedTLS then can't verify the chain and stalls.jsonplaceholder.typicode.com is fronted by a CDN (Vercel) that requires SNI — without setsockopt(sock, SOL_TLS, TLS_HOSTNAME, "jsonplaceholder.typicode.com", ...), the edge either sends a default cert that fails verification or drops the connection entirely.CONFIG_MBEDTLS_HEAP_SIZE) is often 15–30 KB. TLS 1.2 with a full CA bundle + RSA-2048 verify + 16 KB record buffers easily blows past that on ESP32. Failure mode is a silent stall → -116.CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED and matching curve support (SECP256R1) aren't in the Kconfig, ClientHello offers nothing the server accepts.Approach: Enable CONFIG_MBEDTLS_DEBUG=y with CONFIG_MBEDTLS_DEBUG_LEVEL=4 and register a debug callback via mbedtls_ssl_conf_dbg(). The log will show exactly where the handshake dies — "ssl_write_client_hello" without a "parse server hello" points at network/SNI; "certificate verify" errors point at the CA. Also bump CONFIG_MAIN_STACK_SIZE and CONFIG_MBEDTLS_HEAP_SIZE to at least 32 KB and 48 KB respectively before assuming a config bug.
Gotchas: Zephyr's error codes are positive at the socket API but the underlying mbedTLS returns are negative (e.g., -0x7780 for cert verify). Don't confuse them. Also, IPPROTO_TLS_1_2 means "at most 1.2" — if the server insists on TLS 1.3, you need IPPROTO_TLS_1_3 and the corresponding Kconfig.
