The Keycloak Upgrade Ledger

Every upgrade we have rehearsed, with the environment stated and the clock running.

2026-08-26 · run 2026-08-26-runD-ldaps-starttls

Run D: LDAPS works across three majors; what breaks is trust, and it says "SocketReset"

Database
PostgreSQL 16, single node, container
Host
Hetzner CCX33 (fsn1) — 8 vCPU dedicated, 30 GB RAM, local NVMe
Condition
Real LDAP federation — 's untested row: *LDAPS / StartTLS*

Summary

S9 ran federation over plaintext and said TLS is where real deployments break. Two candidate reasons were on the table. One is refuted and one is confirmed, and the confirmed one is confirmed for a reason nobody would guess from the error message.

Refuted: the truststore option rename does not break federation across 23 → 24. A deployment configured the pre-24 way keeps working on 24.0.5 and on 26.7.1, three majors later, with only deprecation warnings.

Confirmed: an untrusted certificate breaks it completely — and Keycloak reports it as SocketReset, with no mention of a certificate anywhere in the response. The server starts perfectly happily; nothing surfaces until something touches LDAP.

Environment

FieldValue
Directorybitnamilegacy/openldap:2.6, TLS on 1636, plaintext 1389 still up
Certificatesprivate CA, server cert CN=ldap, SAN DNS:ldap, DNS:localhost, IP:127.0.0.1, generated by bin/make-ldap-certs.sh
Federation configseed-realm.sh --ldap --ldap-host ldaps://ldap:1636, editMode=READ_ONLY, importEnabled=true
Trust (24+)KC_TRUSTSTORE_PATHS=/opt/keycloak/conf/truststores, a bind-mounted directory
Trust (pre-24)KC_SPI_TRUSTSTORE_FILE_FILE + _PASSWORD, a PKCS12 built with keytool
DatabasePostgreSQL 16, single node, container
HostHetzner CCX33 (fsn1) — 8 vCPU dedicated, 30 GB RAM, local NVMe
JVM heap-Xms1g -Xmx4g
Lab changedocker-compose.ldaps.yml, docker-compose.ldaps-legacy.yml, bin/make-ldap-certs.sh

Breakage observed

A certificate trust failure is reported as SocketReset

A malformed truststore fails the same way as no truststore

Verification

ClaimPrimary sourceChecked
LDAPS federation works with the CA trustedD2 — 3 users imported, HTTP 200, lookup returns alice
Without trust it fails as SocketReset, HTTP 400D1, response quoted
Keycloak starts and passes readiness either wayboth legs reached ready before the sync was attempted
No certificate wording in the response or default loggrepped for PKIX, handshake, truststore, certification — nothing in D1
TLS federation survives 26.0.0 → 26.7.1D3 — READY, 3 users still linked
Pre-24 truststore config still works on 24.0.5 and 26.7.1D5/D6/D7 — syncs return 200, 3 users at every step
Keycloak warns that the pre-24 options are deprecatedboth warnings quoted, from 24.0.5 and 26.7.1
A certBag-only PKCS12 behaves as an empty truststorereproduced, then fixed; keytool -list confirms trustedCertEntry after
StartTLS on 1389tested — works trusted, fails silently (HTTP 200, 0 imported) — 2026-08-26-starttls-1389
Hostname-verification failures (cert whose SAN does not match)tested — hard failure, SSLPeerUnverifiedException, silent at the API — 2026-08-26-starttls-1389
Expired or revoked directory certificatesexpired: tested (silent, CertificateExpiredException); revoked: not tested — no CRL in the lab CA☑ (expired) / ☐ (revoked)
Behaviour when the truststore path exists but is empty on 24+not tested separately — D1's empty directory is that case, but it was not distinguished from "no truststore configured"
editMode=WRITABLE / UNSYNCED over TLSnot tested — still READ_ONLY, as S9 left it

← Back to the Ledger