How to reproduce: 0. Enable store config listener, add user for the tomcat manager app, etc. 1. Configure a connector with SSL using the old syntax in server.xml: <Connector port="8443" SSLEnabled="true" maxThreads="200" scheme="https" secure="true" SSLCertificateFile="/tmp/server.crt" SSLCertificateKeyFile="/tmp/server.key" SSLPassword="changeit"/> 2. Log into manager-host, define a new virtual host configuration, and persist it. 3. Open the server.xml. The connector has been incorrectly saved as: <Connector port="8443" scheme="https" secure="true" SSLCertificateFile="/tmp/server.crt" SSLCertificateKeyFile="/tmp/server.key" SSLEnabled="true" SSLPassword="changeit" SSLProtocol="TLSv1,TLSv1.2,SSLv2Hello,TLSv1.1" keyPass="changeit" sslEnabledProtocols="TLSv1,TLSv1.2,SSLv2Hello,TLSv1.1" sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"> <SSLHostConfig certificateFile="/tmp/server.crt" certificateKeyFile="/tmp/server.key" certificateKeyPassword="changeit"> <Certificate certificateFile="/tmp/server.crt" certificateKeyFile="/tmp/server.key" certificateKeyPassword="changeit"/> </SSLHostConfig> </Connector> Tomcat now won't start, because multiple certificates were defined: 05-Oct-2018 05:00:01.932 WARNING [main] org.apache.tomcat.util.net.SSLHostConfig.setProtocols The protocol [TLSv1.2] was added to the list of protocols on the SSLHostConfig named [_default_]. Check if a +/- prefix is missing. 05-Oct-2018 05:00:01.934 WARNING [main] org.apache.tomcat.util.net.SSLHostConfig.setProtocols The protocol [SSLv2Hello] was added to the list of protocols on the SSLHostConfig named [_default_]. Check if a +/- prefix is missing. 05-Oct-2018 05:00:01.934 WARNING [main] org.apache.tomcat.util.net.SSLHostConfig.setProtocols The protocol [TLSv1.1] was added to the list of protocols on the SSLHostConfig named [_default_]. Check if a +/- prefix is missing. 05-Oct-2018 05:00:01.934 WARNING [main] org.apache.tomcat.util.net.SSLHostConfig.setProtocols The protocol [TLSv1.2] was added to the list of protocols on the SSLHostConfig named [_default_]. Check if a +/- prefix is missing. 05-Oct-2018 05:00:01.935 WARNING [main] org.apache.tomcat.util.net.SSLHostConfig.setProtocols The protocol [SSLv2Hello] was added to the list of protocols on the SSLHostConfig named [_default_]. Check if a +/- prefix is missing. 05-Oct-2018 05:00:01.935 WARNING [main] org.apache.tomcat.util.net.SSLHostConfig.setProtocols The protocol [TLSv1.1] was added to the list of protocols on the SSLHostConfig named [_default_]. Check if a +/- prefix is missing. 05-Oct-2018 05:00:01.935 SEVERE [main] org.apache.tomcat.util.digester.Digester.endElement End event threw exception java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.util.IntrospectionUtils.callMethod1(IntrospectionUtils.java:377) at org.apache.tomcat.util.digester.SetNextRule.end(SetNextRule.java:145) at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:958) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609) at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:183) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1339) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643) at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1453) at org.apache.catalina.startup.Catalina.load(Catalina.java:605) at org.apache.catalina.startup.Catalina.load(Catalina.java:656) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:306) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:491) Caused by: java.lang.IllegalArgumentException: Multiple certificates were specified and at least one is missing the required attribute type at org.apache.tomcat.util.net.SSLHostConfig.addCertificate(SSLHostConfig.java:257) ... 27 more 05-Oct-2018 05:00:01.937 WARNING [main] org.apache.catalina.startup.Catalina.load Catalina.start using conf/server.xml: Error at (31, 83) : Multiple certificates were specified and at least one is missing the required attribute type 05-Oct-2018 05:00:01.937 SEVERE [main] org.apache.catalina.startup.Catalina.start Cannot start server. Server instance is not configured. OS: RHEL 7.5 Tomcat version: 9.0.12 Java: openjdk version "1.8.0_171"
Attribute duplication is causing problems. The fix will be in 8.5.35 and 9.0.13.
This has cropped up again, tomcat 9.0.13. Same reproducer, but: TLS connector config: <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" secure="true" scheme="https" SSLEnabled="true" keystoreFile="/tmp/server.jks" keystorePass="changeit" clientAuth="true"/> Outputs: <Connector port="8443" scheme="https" secure="true" SSLEnabled="true" SSLVerifyClient="REQUIRED" clientAuth="REQUIRED" sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"> <SSLHostConfig> <Certificate certificateKeystoreFile="/tmp/ssl/self_signed/server.jks" type="UNDEFINED"/> </SSLHostConfig> </Connector> Tomcat does not start. Notice there's a missing closing sign in the Connector tag, i.e.: <Connector port="8443" scheme="https" secure="true" SSLEnabled="true" should be: <Connector port="8443" scheme="https" secure="true" SSLEnabled="true"> (closing character added at the end). When I fix that manually, Tomcat starts.
Note that the following connector now works: <Connector port="8443" SSLEnabled="true" maxThreads="200" scheme="https" secure="true" keystoreFile="/tmp/server.jks" SSLPassword="changeit"/> It gets correctly saved as: <Connector port="8443" scheme="https" secure="true" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeyPassword="changeit" certificateKeystoreFile="/tmp/server.jks" type="UNDEFINED"/> </SSLHostConfig> </Connector>
The issue is not what is described, all XML elements are properly closed. However, the SSL attributes that are used by storeconfig are duplicated in multiple locations and this is difficult to maintain. This is fixed for now, but if more issues remain or reappear in that area, they will ultimately be resolved in Tomcat 10.