Solving problems calling out of CF via https, by updating JVM
If you’re getting errors in calling out to https urls from CF, you may not need to “import new certificates”. You may merely need to update the JVM that CF uses.
Over the years I have had clients present to me, or have seen people write on the web, that they were getting error such as the following in CF, when trying to do a cfhttp call to an https URL:
I/O Exception: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I/O Exception: peer not authenticated
And such folks have found various blog posts (perhaps from years gone by) suggesting a need to import new SSL certificates into CF using the Java keytool command, or to add args like -Dhttps.protocols=TLSv1.1,TLSv1.2.
TLDR: Such jvm tweaks may well have been needed for some problems in the past (or may be needed still in some unique cases), but in most cases the solution to such failing ssl/tls calls out of cf is much simpler, and it could benefit many readers to hear this:
They probably just needed to update their JVM (that CF was using).
Let me explain.
What might be the real cause of the problem?
Those two problems above are indeed different, and have different causes, but again they both may be solved by just updating the CF JVM.
First, a very common reason for this sort problem is simply that the destination server being called (such as in a cfhttp, cfmail, cfftp, etc.) has changed what SSL or TLS versions or protocols it supports. And those may be versions that the JVM that CF is relying on DOES NOT SUPPORT.
Second, the destination server may have changed something about its server certificates, such that the client certs (or root certs) stored within the CF JVM can no longer work with those newer certs. These may be certificates you did install in the past, or merely the ones built into the java certificate store (cacerts, in the lib/security folder of the JVM that CF is using.)
These are how the errors above you experience can appear “suddenly”, when you “haven’t changed anything”. The change was made in the server or service you are calling, like a payment gateway, or a web service, or some API server, etc.
Why updating the JVM that CF uses may help
And often the problem is simply that the JVM which underlies CF is just old (perhaps very old). Over the years, the JVM has been updated to support more and more recent protocols (and indeed to drop support for older ones), and to have more and more updated certs by default.
In the case of the client which prompted me to go ahead and write this, they were running on ColdFusion 11 as I said, but this could happen with other CF versions.
They key point was that in their case, they had not updated their CF to run on a more recent Java version, so they were on the original JVM that came out with CF 11, Java 1.8.0_25. To put things in perspective, as of this writing, the latest Java 8 version is is 1.8.0_212. That update 25 was from the time when CF11 came out–in 2014!
So all we did was to simply update to Java 8 update 212 (from Apr 2019), and that solved his problem.
How to go about updating the JVM CF uses: questions you may have
When I say “all we did was to simply update” the Java that underlies CF, you may have lots of questions about that. 🙂 Here’s good news, when the most recent Java updates (212 for Java 8, and 4 for Java 11 at the time of this writing) came out in April, I did a blog post where I addressed typical questions you may have about updating the JVM, including:
- where to download the latest Java updates, from Adobe (and why)
- where to find more about HOW TO update the JVM CF that uses
- what versions of CF support what versions of Java, including Java 11
- how to recover if you make a mistake trying to update the JVM CF that uses
(I should add that even updating to even slightly older Java update than the very latest could solve this problem as well, for those who “don’t want to be on the bleeding edge”. But it’s generally best to be on the latest available update of the Java version supported by your version of CF, and Adobe does recommend that.)
Whether you’ll be updating to that specific Java update or not, check do out that other post for answers to those and some other common questions about updating the JVM that CF users.
What you may not need to bother with
So really, that was it: update the JVM. They really did not need to do any other jvm tweaks.
First, they did not need to import certificates after all. You may see resources on the web proposing that. Indeed, one of the resources my client had found (which led them to ask if they needed to go about importing a new cert) was this blog post of years ago from the venerable hass.de site.
He was explaining why importing certs may be needed to solve some SSL problems. And sometimes it may be. Again, for example, my client prompting this post was using CF11 and the original Java 1.8.0_25 which came out 5 years ago. It may well be that such an old JVM had expired certificates and root certs, leading to a need for some (at some time in the past) to do such cert imports, before a newer jvm included the better certs. (Indeed, sometimes people have been importing certs by rote for years thinking they needed them, when instead all they needed was to update the JVM to get the better certs and root certs it would have by default.)
But again just updating Java worked for my client and I hope it may for some of my readers.
And that hass.de blog did indeed mention in passing that “an update to latest Java sometimes also help, too.” That would be easy to miss amid all else in the post. One reason I point this out here is that sadly that hass.de site no longer allows comments, so I couldn’t add this clarification there. (I get it that more and more sites are not permitting comments. I see the pros AND cons.)
Second, as for why adding the Dhttps.protocols arg may not help or be needed: again you may see resources on the web proposing adding those as a solution for some cf ssl issues. But it is not the right solution for this more common problem (of the destination server changing what it supports, and that being something that the JVM CF is running on does NOT support).
This Dhttps.protocols arg would be for limiting what protocols CF/the JVM should use. But the SSL negotiation between CF and the destination server (such as in a CFHTTP call) should cause CF to use whatever the best protocol the destination DOES support. But again, if the ones that the destination DOES support are not ones that the JVM underlying CF supports, you will get the error. As such, the args won’t help, and really it’s rare that you need this arg anyway to “limit” what protocols CF would try to use.
Bottom line: Try updating the Java that CF uses
My goal here was just to get the word out that for THAT error above (and perhaps other failures to call out of CF to https pages), you may not need to bother importing certs. You may just need to update the JVM. It’s worth a shot. And you can easily revert back to the previous JVM version, if you follow best practices in updating the JVM that CF users, as discussed in resources I point out in that other post.
Hope all this may help some readers.