Overview of the Problem
Secure Sockets Layer (SSL) and Transport Layer Security (TLS) are the cryptographic protocols that provide confidentiality and integrity for HTTPS and other secure protocols (SMTPS, LDAPS) used by ColdFusion. SSL/TLS “issues” in ColdFusion usually appear when your code or server attempts to:
- Make outbound secure calls (cfhttp, cfmail over TLS, cfldap, Web services, REST, package manager) and fails with handshake or certificate errors.
- Serve inbound HTTPS (Tomcat directly or through IIS/Apache) and clients fail to connect securely.
These failures are commonly due to certificate trust problems, protocol/cipher mismatches, hostname verification issues, missing intermediate certificates, expired or revoked certificates, or network devices (proxies, load balancers) intercepting TLS.
Symptoms include stack traces such as “PKIX path building failed,” “SSLHandshakeException: handshake_failure,” “No appropriate protocol,” or “certificate_unknown.” Understanding where the problem sits—client/outbound vs. server/inbound—is the first key to resolving it.
Possible Causes
Outbound (ColdFusion acting as a client)
- Untrusted server certificate or missing intermediate CA
- Expired or not-yet-valid certificate
- Hostname mismatch (CN/SAN doesn’t match target host)
- TLS protocol/cipher mismatch (e.g., server requires TLS 1.2/1.3; client can’t negotiate)
- Server requires SNI, but connection is by IP or SNI disabled
- Client certificate (mutual TLS) required, missing, or incorrect
- Corporate proxy performing TLS interception (MITM) with untrusted root
- OCSP/CRL revocation checks timing out or failing
- Outdated JVM with disabled algorithms or limited TLS support
Inbound (ColdFusion/Tomcat or front-end acting as a server)
- Keystore misconfiguration (wrong alias, password, or format)
- Certificate chain incomplete on the server
- Cipher/protocol Configuration excludes what clients support
- Front-end (IIS/Apache/nginx) SSL termination misconfigured
- SNI/virtual hosting not configured for all hostnames
- Certificate expired or renewed but not reloaded
Quick Cause / Solution Reference
-
PKIX path building failed / unable to find valid certification path:
- Solution: Import server’s CA chain (prefer intermediate CA, not leaf) into ColdFusion JVM truststore or use a dedicated truststore.
-
handshake_failure / No appropriate protocol:
- Solution: Align TLS versions and ciphers. Update JVM; enable TLS 1.2/1.3; adjust jdk.tls.disabledAlgorithms if necessary.
-
Hostname mismatch:
- Solution: Use the correct hostname matching the certificate SAN; fix DNS; avoid using IP if the cert is for FQDN.
-
Client cert required (mutual TLS):
- Solution: Provide PKCS12 or JKS client cert/keys with proper password and alias; reference from cfhttp/cfldap/mail or JVM args.
-
Works from browser but not from ColdFusion:
- Solution: Browser trusts system CAs; ColdFusion trusts the JVM’s cacerts. Import the missing CA into the JVM truststore CF uses or switch CF to an external JDK with up-to-date CAs.
-
Proxy intercepting TLS:
- Solution: Import proxy’s root CA to JVM truststore or bypass proxy for the target.
Step-by-Step Troubleshooting Guide
Step 1: Identify the scope and path
- Outbound call failing (cfhttp/cfmail/cfldap/web service)?
- Inbound HTTPS failing (Tomcat vs. front-end web server)?
- Which environment (dev/test/prod)? Which hostname/port?
- Which ColdFusion version and which Java/JDK version? Check in ColdFusion Administrator > Settings Summary (Java Home, Version).
H5: Why it matters
Outbound uses Java’s JSSE as a client; inbound uses server SSL config (Tomcat or front-end). Fixes differ sharply.
Step 2: Capture the exact error and stack trace
Look in cfusion/logs (e.g., exception.log, application.log). Copy the full exception. Common examples:
- javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
- sun.Security.validator.ValidatorException: PKIX path building failed
- javax.net.ssl.SSLException: hostname in certificate didn’t match
- java.security.cert.CertificateExpiredException
The exact wording points to the cause and next steps.
Step 3: Test the target endpoint outside ColdFusion
Use OpenSSL or curl from the ColdFusion server to the target:
Show certificate chain and TLS details (with SNI)
openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts
Force protocol to test compatibility
openssl s_client -connect api.example.com:443 -servername api.example.com -tls1_2
Quick HTTP/HTTPS check with verbose output
curl -Iv https://api.example.com/resource
If these fail, the problem is not ColdFusion-specific (network, Server config, or certificate chain issue). If these succeed but ColdFusion fails, focus on the JVM truststore and Configuration.
Step 4: Enable detailed JVM SSL debug logging
Temporarily enable SSL debug to view the handshake:
-
Edit jvm.config (e.g., C:\ColdFusion2021\cfusion\bin\jvm.config or /opt/coldfusion/cfusion/bin/jvm.config).
-
Append to java.args:
-Djavax.net.debug=ssl,handshake,record -
Restart the ColdFusion service.
-
Reproduce the issue and review coldfusion-out.log (or console logs).
Sample snippets you may see:
ClientHello, TLSv1.2
Cipher Suites: [TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, …]
…
ServerHello, TLSv1.2
…
Certificate chain
…
Fatal alert: handshake_failure
Turn this off after Troubleshooting to reduce log noise.
Step 5: Verify truststore and import missing CA chain
ColdFusion trusts certificates present in the JVM truststore (cacerts). Find which JVM ColdFusion uses in the Admin > Settings Summary (Java Home). Then:
List trusted CAs
keytool -list -keystore “
Export the server’s cert chain (from openssl output or browser)
Save intermediate/root certs as .cer/.pem files
Import intermediate/root CA (preferred) to cacerts
keytool -importcert -alias example-intermediate \
-file /path/intermediate.cer \
-keystore “
Notes:
- Prefer importing the issuing Intermediate CA rather than the leaf server certificate.
- If your organization mandates a separate truststore, create one and point ColdFusion to it:
-Djavax.net.ssl.trustStore=/path/to/truststore.jks
-Djavax.net.ssl.trustStorePassword=changeit
Restart ColdFusion and test again.
Step 6: Check TLS protocol and cipher compatibility
Modern servers often require TLS 1.2 or 1.3. Ensure your JVM supports it and that disabled algorithms don’t block negotiation.
- Verify Java version in CF Admin. Consider updating to a recent, supported JDK.
- Review
/conf/security/java.security (or lib/security/java.security on older JDKs): - jdk.tls.disabledAlgorithms
- If a handshake fails due to disabled algorithms, either enable better ciphers on the server or carefully adjust the disabled list (prefer changing the server; changing client policies can lower security).
To test forcing a protocol during Debugging:
Not a permanent fix—just for testing via system property
-Dhttps.protocols=TLSv1.2,TLSv1.3
Ensure server and client overlap in at least one protocol/cipher.
Step 7: Handle SNI and hostname verification
- Always connect using the correct FQDN that matches the certificate SAN.
- Avoid connecting by IP when the server uses SNI (you’ll get the wrong certificate).
- Ensure SNI is not disabled in the JVM:
-Djsse.enableSNIExtension=true (default true on modern Java)
Hostname verification errors:
- Fix DNS or use the correct host.
- Renew the certificate with proper SANs if necessary.
- Do not disable hostname verification in production; it defeats TLS security.
Step 8: Client certificates (mutual TLS)
If the server requires a client certificate:
- Use a PKCS12 (recommended) or JKS keystore containing the client key and certificate chain.
- For cfhttp, supply client certificate attributes (e.g., clientCert and clientCertPassword for a PKCS12 file). Example:
<cfhttp url=”https://partner.example.com/secure”
method=”get”
clientCert=”/opt/certs/client.p12″
clientCertPassword=”S3cret!”
result=”res”>
- Alternatively, set JVM-level properties for global client cert usage:
-Djavax.net.ssl.keyStore=/opt/certs/client.p12
-Djavax.net.ssl.keyStorePassword=S3cret!
-Djavax.net.ssl.keyStoreType=PKCS12
Ensure the keystore alias is correct and includes the full chain.
Step 9: Proxies and TLS interception
If using a corporate proxy:
- ColdFusion-level proxy settings (Admin or cfhttp proxyServer/proxyPort) may route requests through a TLS-intercepting proxy.
- Import the proxy’s root CA into the JVM truststore so connections validate.
- Alternatively, bypass the proxy for specific hosts via proxy exclusions.
Step 10: Inbound HTTPS via Tomcat or a front-end
Most ColdFusion deployments terminate HTTPS at IIS/Apache/nginx, not Tomcat. Identify where TLS terminates.
-
If front-end:
- Check the web server’s SSL certificate, chain, protocols, and ciphers.
- Validate SNI bindings for each hostname.
- Confirm the connector to Tomcat (AJP/HTTP) is healthy.
-
If Tomcat terminates SSL (server.xml):
<Connector
port=”8443″
protocol=”org.apache.coyote.http11.Http11NioProtocol”
SSLEnabled=”true”
maxThreads=”200″
scheme=”https”
secure=”true”>
- Restart ColdFusion (Tomcat) after changes.
- Validate with:
openssl s_client -connect your-cf-host:8443 -servername your-cf-host -showcerts
Step 11: Special cases in ColdFusion Features
H5: cfmail (SMTPS/STARTTLS)
- In CF Admin > Mail, set port and enable SSL/TLS accordingly.
- For STARTTLS on port 587, ensure “Use TLS” is enabled, not SMTPS on 465.
- If the mail server uses a private CA, import its CA into the JVM truststore.
H5: cfldap (LDAPS)
- Use ldaps://host:636 with correct CA chain in truststore.
- Some LDAP servers require specific ciphers; check with openssl s_client.
- For mutual TLS, supply client certificate via JVM properties.
H5: Web services/REST/Package Manager
- All rely on the same JVM truststore and protocols.
- For Adobe Package Manager (CommandBox/CFPM), import proxy CA if required.
Logs, Commands, and Configuration Examples
Enable SSL debug in jvm.config
jvm.config (excerpt)
java.args=-Xms1024m -Xmx2048m -Djavax.net.debug=ssl,handshake,record -Djava.net.preferIPv4Stack=true
Importing a CA certificate
Save the intermediate CA to /tmp/intermediate.cer
keytool -importcert -alias partner-int -file /tmp/intermediate.cer \
-keystore “
Sample PKIX error (application.log)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Testing protocols and SNI with OpenSSL
openssl s_client -connect api.partner.com:443 -servername api.partner.com -tls1_2 -cipher ‘ECDHE+AESGCM’
Common mistakes and How to Avoid Them
-
Importing the leaf certificate instead of the issuing intermediate CA
- Avoid by importing the entire chain or the intermediate CA specifically.
-
Editing the wrong JVM’s cacerts
- Always confirm the Java Home used by ColdFusion in the Admin Settings Summary before importing.
-
Disabling security Features (hostname verification, revocation checks) as a “fix”
- These are last-resort diagnostics. Restore defaults after testing.
-
Assuming browser trust equals JVM trust
- ColdFusion uses the JVM truststore, not the OS/browser store.
-
Forgetting to restart ColdFusion after truststore or jvm.config changes
- Many changes require a restart to take effect.
-
Overly broad changes in java.security (weakening disabled algorithms)
- Prefer upgrading Java or fixing the server side rather than weakening client policies.
Prevention Tips / Best practices
- Keep ColdFusion and the underlying JDK up to date; adopt LTS JDKs and apply security updates regularly.
- Automate certificate renewals (ACME/Let’s Encrypt) and include proper SANs; ensure intermediate chains are served correctly.
- Use a dedicated truststore per application or environment for third-party/private CAs; document alias names and sources.
- Standardize on TLS 1.2/1.3 and modern ECDHE+AES-GCM ciphers; avoid legacy protocols (TLS 1.0/1.1, SSLv3).
- Monitor certificate expiry with alerts; test renewals in staging first.
- Use SNI-aware configurations and connect via FQDNs that match certs.
- For corporate proxies, distribute the corporate root CA to all JVMs via Configuration management.
- Keep a rollback plan: backup jvm.config, truststores, and server.xml before changes.
Key Takeaways
- Most ColdFusion SSL/TLS failures are trustchain or protocol negotiation problems between the JVM and the remote server.
- Verify the exact JVM used by ColdFusion and manage its truststore carefully; don’t assume browser trust applies.
- Use OpenSSL/curl to confirm remote endpoints, then JVM SSL Debugging to pinpoint handshakes.
- Prefer importing intermediate CAs over leaf certs and maintain separate truststores when appropriate.
- Keep Java, ColdFusion, and certificates current to reduce compatibility problems.
FAQ
How do I fix “PKIX path building failed: unable to find valid certification path to requested target”?
Import the issuing intermediate CA (or full chain) into the JVM truststore that ColdFusion actually uses. Confirm the Java Home in ColdFusion Admin, then use keytool -importcert to add the intermediate CA. Restart ColdFusion and retry.
Why does a URL load fine in my browser but fails in cfhttp with an SSL error?
Browsers use the OS trust store and may have automatic trust updates. ColdFusion uses the JVM truststore, which may not include the same CAs. Import the missing CA into the JVM truststore (or use a dedicated truststore) and restart ColdFusion.
How can I force or enable TLS 1.2/1.3 for outbound requests?
Run ColdFusion on a modern JDK that supports TLS 1.2/1.3. If needed for diagnostics, set -Dhttps.protocols=TLSv1.2,TLSv1.3 in jvm.config. Avoid weakening java.security policies; instead, update your JVM and ensure the remote server supports strong ciphers.
Can I use a custom truststore instead of modifying cacerts?
Yes. Create a JKS/PKCS12 truststore with only the necessary CAs and point ColdFusion to it with -Djavax.net.ssl.trustStore and -Djavax.net.ssl.trustStorePassword in jvm.config. This isolates app-specific trust and simplifies migrations.
After renewing a certificate on Tomcat/IIS, clients still see the old certificate. What did I miss?
You likely need to restart the service or reload the binding. For Tomcat, restart ColdFusion/Tomcat. For IIS/Apache/nginx, restart or reload the web server. Also verify the new certificate chain is complete and the correct SNI binding is updated.
