I generated a letsencrypt certificate for my openfire server and ran into the same problem reported at Using cert in Openfire (XMPP-Server) - Let's Encrypt Community Support. Even though the certificate has the XMPP domain as an alternate name, it doesn't seem to pass validation. Complicating matters, the error reported in the admin console does not provide any details. Instead, you have to look in Openfire's info.log:
2016.03.02 09:25:47 org.jivesoftware.openfire.keystore.IdentityStore - The supplied certificate chain does not cover the domain of this XMPP service ('snurgle.org'). Instead, it covers [jabber.snurgle.org]
The code (Openfire/IdentityStore.java at master · igniterealtime/Openfire · GitHub) does seem to be trying to match the domain against a list of values returned by CertificateManager.getServerIdentities, but it seems to only be returning the Subject CommonName of the cert. Having done the workaround described in the discussion linked above, the cert does import and I can see in the admin console the expected Subject Alternative Names which include the XMPP service domain. Someone had reported in 2014 that they had trouble with a cert with more than 2 alternative names at [bug] Cannot import a certificate with 2 altsubject names, which also applies to my case (the cert I generated has three, snurgle.org, jabber.snurgle.org and conference.snurgle.org) but it sort of seems like that might be a red herring?
Previously I had used a StartCom cert which did NOT seem to have this problem. Looking at the two certs, the StartCom cert does not have the domain as the CommonName either (it uses conference.snurgle.org), but snurgle.org is listed as a "Subject Alternative Name (Other Name)" with a value of "xmppAddr snurgle.org" whereas the letsencrypt cert has only "Subject Alternative Name (DNS Name)" with a value of "snurgle.org".
I'm not an SSL expert (apologies if I am using incorrect terminology in here) so it is very possible this is all expected somehow, but the fact that the cert seems to work ok once successfully imported seems to imply that there's some confusion somewhere. Happy to provide more information or debugging.