title: javax.net.ssl.SSLException: Certificate doesn't match any of the subject alternative names
body: <p>I recently added LetsEncrypt certificates to my server and my java applet is having problems connecting using TLS.</p>
  
  <p>My applet uses Apache HttpClient.</p>
  
  <p>My web server is Apache 2,4, and I have a few virtual hosts set up as subdomains of my main domain (foo.com - not my real domain name).</p>
  
  <p>When I run my applet on the staging subdomain (e.g. it runs off <a href="https://staging.foo.com" rel="noreferrer">https://staging.foo.com</a>), I get the following error:</p>
  
  <pre><code>javax.net.ssl.SSLException: Certificate for &lt;staging.foo.com&gt; doesn't match any of the subject alternative names: [developer.foo.com]
  at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:165)
  at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:61)
  at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:141)
  at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:114)
  at org.apache.http.conn.ssl.SSLSocketFactory.verifyHostname(SSLSocketFactory.java:580)
  at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:554)
  at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:412)
  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:179)
  at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:328)
  at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:612)
  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:447)
  at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:884)
  at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
  at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
  ...(cut)
  at javax.swing.SwingWorker$1.call(SwingWorker.java:295)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at javax.swing.SwingWorker.run(SwingWorker.java:334)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p>I have no idea what's going on.</p>
  
  <p>First of all, I have no idea how Java knows that developer.foo.bar is one of my virtual hosts (although this virtual host is the first one, alphabetically, that has SSL turned on).</p>
  
  <p>I've looked at the certificate detail for staging.foo.com, and the only name listed under the "Subject Alternative Name" field is staging.foo.com.</p>
  
  <p>So where is it getting developer.foo.com from?</p>
  
  <p>And how do I fix this problem?</p>
  
  <p>I'm using Firefox on OS X El Capitan 10.11.6 with the following Java plugin version info:</p>
  
  <pre><code>Java Plug-in 11.102.2.14 x86_64
  Using JRE version 1.8.0_102-b14 Java HotSpot(TM) 64-Bit Server VM
  </code></pre>
  
  <p>This is the Apache conf file for staging.foo.com:</p>
  
  <pre><code>&lt;IfModule mod_ssl.c&gt;
  &lt;VirtualHost *:443&gt;
      ServerName staging.foo.com
      ServerAlias www.staging.foo.com
  
      # Turn on HTTP Strict Transport Security (HSTS). This tells the
      # client that it should only communicate with this site using
      # HTTPS. See
      # https://raymii.org/s/tutorials/HTTP_Strict_Transport_Security_for_Apache_NGINX_and_Lighttpd.html
      Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
  
      # The following is used to tunnel websocket requests to daphne, so
      # that Django Channels can do its thing
      ProxyPass "/ws/" "ws://localhost:8001/ws/"
      ProxyPassReverse "/ws/" "ws://localhost:8001/ws/"
  
      # The following is used during deployment. Every page request is
      # served from one static html file.
      RewriteEngine       on
      RewriteCond         /home/www-mm/staging.foo.com/apache/in_maintenance -f
      RewriteRule .*      /home/www-mm/staging.foo.com/static/maintenance/maintenance.html
  
      # Use Apache to serve protected (non-static) files. This is so that
      # Apache can deal with ranges
      XSendFile on
      XSendFilePath /home/www-mm/staging.foo.com/user_assets
  
      # Limit uploads - 200MB
      LimitRequestBody 209715200
  
      Alias /static/ /home/www-mm/staging.foo.com/serve_static/
      Alias /robots.txt /home/www-mm/staging.foo.com/apache/serve-at-root/robots.txt
  
      &lt;Directory /home/www-mm/staging.foo.com/serve_static&gt;
          AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/json
          Order deny,allow
          Require all granted
      &lt;/Directory&gt;
  
      # Videos uploaded via staff to home page should never cache,
      # because they can change at any time (and we don't know if the
      # URLs will change or not). Etags are used and only headers are
      # sent if the files in question aren't modified (we get a 304
      # back)
      &lt;Directory /home/www-mm/staging.foo.com/serve_static/video&gt;
          ExpiresActive On
          # Expire immediately
          ExpiresDefault A0
      &lt;/Directory&gt;
  
      # The following ensures that the maintenance page is never cached.
      &lt;Directory /home/www-mm/staging.foo.com/static/maintenance&gt;
          ExpiresActive On
          # Expire immediately
          ExpiresDefault A0
          Require all granted
      &lt;/Directory&gt;
  
      # Hide uncompressed code from prying eyes. Python needs access to this code for the css compressor
      &lt;Directory /home/www-mm/staging.foo.com/serve_static/js/muso&gt;
          &lt;Files ~ "\.js$"&gt;
              Deny from all
          &lt;/Files&gt;
          # Order deny,allow
          # Deny from all
      &lt;/Directory&gt;
  
      # Hide uncompressed code from prying eyes. Python needs access to this code for the css compressor
      &lt;DirectoryMatch "/home/www-mm/staging.foo.com/serve_static/js/dist/.*/muso"&gt;
          Order deny,allow
          Deny from all
      &lt;/DirectoryMatch&gt;
  
      &lt;Directory /home/www-mm/staging.foo.com/apache&gt;
          &lt;Files django.wsgi&gt;
              Order deny,allow
              Require all granted
          &lt;/Files&gt;
      &lt;/Directory&gt;
  
      WSGIScriptAlias / /home/www-mm/staging.foo.com/apache/django.wsgi
      WSGIDaemonProcess staging.foo.com user=www-mm group=www-mm
      WSGIProcessGroup staging.foo.com
  
      ErrorLog /var/log/apache2/staging.foo.com-error.log
      CustomLog /var/log/apache2/staging.foo.com-access.log combined
  
      SSLCertificateFile /etc/letsencrypt/live/staging.foo.com/fullchain.pem
      SSLCertificateKeyFile /etc/letsencrypt/live/staging.foo.com/privkey.pem
      Include /etc/letsencrypt/options-ssl-apache.conf
  &lt;/VirtualHost&gt;
  &lt;/IfModule&gt;
  </code></pre>
  
  <p>The SSL sections were added by certbot, the LetsEncrypt CLI tool.</p>
  
  <p>I should add that accessing each of these subdomains in a modern browser (such as Chrome) is fine.</p>