I want to flag something that cost us two production incidents before we pinned it down, because the failure signature looks nothing like its cause and I suspect others will hit it as Lucee 7 adoption grows.
TL;DR: the PDF extension that ships bundled with Lucee 7 registers its BouncyCastle 1.38 (2007) as a JVM security provider at engine boot, ahead of the JVM’s own providers. On Java 21 its ancient EC/ECDH implementations then poison every outbound TLS handshake the JVM attempts - JDBC with TLS, cfhttp, SMTP, everything - while the server otherwise appears healthy.
Environment
- Lucee 7.0.4+34 (also reproduced on an earlier 7.0.x), CommandBox 6.3.3
- Ubuntu 24.04, OpenJDK 21.0.11
- PDF extension 2.0.1.0 as bundled with the engine (we never installed it explicitly and never call any of its functions - all our PDFs come from wkhtmltopdf)
- MySQL 8 (AWS RDS) over JDBC with TLS on (Connector/J default sslMode=PREFERRED)
Symptoms
From the moment the engine finishes booting:
- Every datasource query:
Communications link failure - The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. - Every cfhttp to an https URL:
Connection Failure, and with errorDetail exposed:Could not generate ECDH keypair/EC Key Pair Generator not initialised - Anything else that leaves the JVM over TLS fails silently the same way.
Nothing in the symptoms points at PDFs. If you go looking for “Communications link failure” you find a decade of threads with a dozen different causes (expired CAs, driver mismatches, keystores, TLS version mismatches) - none of them this.
Diagnosis
createObject("java", "java.security.Security").getProviders()showed BC 1.38 sitting FIRST in the provider list, ahead of SunEC / SunJSSE. Lucee core itself carries a modern BC that is perfectly fine - the 1.38 comes from the PDF extension’s bundles (bouncycastle.prov/mail/tsp-1.38.0.jar, alongside icepdf.core-3.1.0.3, org.lucee.pdfbox-3.0.0.RC101 and flyingSaucer).- A binary grep across every bundle jar for
insertProviderAtmatched only icepdf.core-3.1.0.3.jar. The old IceSoft-era IcePDF registers BouncyCastle as a JVM-wide provider for encrypted-PDF support. (The modern IcePDF fork made the provider configurable via theorg.icepdf.core.pobjects.security.providersystem property - effectively acknowledging that hard-registering it was a problem. Apache PDFBox has the same theme in PDFBOX-2963, “Remove Bouncy Castle Provider Reference”.) - BC 1.38 predates most of the named curves and provider plumbing modern JSSE relies on, so once it answers first for EC/ECDH, every handshake dies.
- Registering a good provider from
onApplicationStartdoes NOT help: the extension registers at engine boot, before any application code, and JSSE caches the poisoned state.
Proof by natural experiment
Removing the extension (the .lex, its installed folder, the icepdf / bouncycastle 1.38 / pdfbox / flyingSaucer bundle jars, and its .CFConfig.json extensions entry), then restarting: 60/60 concurrent TLS JDBC connections clean, cfhttp fine, TLS everywhere restored, with nothing else changed.
Two days later a CommandBox restart resolved our then-floating lucee@7 engine pin to a new patch release; the fresh engine re-deployed its bundled extensions, the PDF extension came back, and the identical failure returned within two minutes of boot. Stripping it again fixed it again. Cause, effect, cause, effect.
Workaround (what we run now)
We pin the exact engine version in server.json so an engine redeploy never happens implicitly, and run an idempotent strip after any engine start:
rm -f <server-home>/WEB-INF/lucee-server/context/extensions/available/66E312DD-D083-27C0-64189D16753FD6F0*.lex
rm -rf <server-home>/WEB-INF/lucee-server/context/extensions/installed/66E312DD-D083-27C0-64189D16753FD6F0*
rm -f <server-home>/WEB-INF/lucee-server/bundles/icepdf.core-*.jar \
<server-home>/WEB-INF/lucee-server/bundles/bouncycastle.*-1.38.0.jar \
<server-home>/WEB-INF/lucee-server/bundles/org.lucee.pdf*.jar \
<server-home>/WEB-INF/lucee-server/bundles/org.lucee.flyingSaucerPDF-*.jar \
<server-home>/WEB-INF/lucee-server/bundles/org.lucee.pdfbox*.jar
# plus remove the 66E312DD-... entry from .CFConfig.json's extensions array
Obviously that only suits apps that do not use cfdocument/cfpdf.