# Install a TLS certificate on Apache Tomcat

Tomcat 8.5 and later can read PEM files directly — set `certificateFile`, `certificateKeyFile` and `certificateChainFile` on an `SSLHostConfig`, and no keystore is needed at all. The older keystore route still works: convert to PKCS#12 with `openssl pkcs12 -export` and point `keystoreFile` at it with `keystoreType="PKCS12"`. Prefer PKCS#12 over JKS, which has been deprecated since Java 9. The most common failure is a keystore password that differs from the key password, which Tomcat does not handle.

Source: https://certguru.io/platforms/tomcat/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

## The modern way — PEM directly

Tomcat 8.5 introduced `SSLHostConfig`, which reads PEM without any keystore:

    
`}
/>

| Placeholder | What to put there |
| --- | --- |
| `certificateFile` | The server certificate alone — *not* the full chain. |
| `certificateChainFile` | The intermediates. Tomcat is one of the few servers with a separate directive for this. |
| `certificateKeyFile` | The private key, unencrypted PKCS#8. |

> **Tomcat wants the chain separately**
>
> Unlike nginx and modern Apache, Tomcat has a dedicated `certificateChainFile`. Concatenating the
>   chain into `certificateFile` here is the wrong shape — put the leaf in one and the intermediates
>   in the other.

The key must be PKCS#8. If yours starts `BEGIN RSA PRIVATE KEY`, convert it — writing to a new
file rather than over the original, so a mistake is recoverable:

```bash
openssl pkcs8 -topk8 -in pkcs1.key -out private-pkcs8.key -nocrypt
```

See [PKCS#1 to PKCS#8](/convert/pkcs1-to-pkcs8/).

## The keystore way

Required on Tomcat before 8.5, and still common.

*Build a PKCS#12 keystore*

```bash
openssl pkcs12 -export \
  -in certificate.crt -inkey private.key -certfile chain.crt \
  -name tomcat -out keystore.p12 -passout pass:changeit
```

`}
/>

> **The two-password trap**
>
> A keystore has a store password and, separately, a password on each key entry. Tomcat assumes they
>   are identical and fails with `Cannot recover key` when they are not — a message that points nowhere
>   useful. Exporting from OpenSSL with a single `-passout` sets both, which is why this route avoids
>   the problem.

## Starting from a PFX you were given

```bash
cp certificate.pfx /opt/tomcat/conf/keystore.p12
```

A PFX *is* a PKCS#12 keystore — no conversion needed, just point `keystoreFile` at it and set
`keystoreType="PKCS12"`. Find the alias first, because Tomcat needs it:

```bash
keytool -list -keystore certificate.pfx -storetype PKCS12
```

## Restart and verify

```bash
systemctl restart tomcat
```

*What is actually being served*

```bash
openssl s_client -connect example.com:8443 -servername example.com /dev/null \
  | grep -E "Verify return code|subject="
```

*Is the chain complete?*

```bash
openssl s_client -connect example.com:8443 -servername example.com -showcerts /dev/null \
  | grep -c "BEGIN CERTIFICATE"
```

Expected output:

```
2
```

## Common Tomcat failures

| Symptom | Cause | Fix |
| --- | --- | --- |
| `Cannot recover key` | Key password ≠ keystore password | Set both the same |
| `Alias name [x] does not identify a key entry` | Wrong `keyAlias`, or a certificate-only entry | `keytool -list` and use the real alias |
| Connector fails to start, no detail | Wrong `keystoreType` for the file | `PKCS12` for `.p12`/`.pfx`, `JKS` for `.jks` |
| Works, but clients report an untrusted issuer | `certificateChainFile` missing | Point it at the intermediates |
| PEM key rejected | Key is PKCS#1, not PKCS#8 | [Convert it](/convert/pkcs1-to-pkcs8/) |


## Frequently asked questions

### Do I still need a keystore?

Not on Tomcat 8.5 or later, which reads PEM directly via `certificateFile` and friends. That removes the conversion step and makes ACME renewal far simpler, since certbot already writes PEM.

### Why does Tomcat fail with "Cannot recover key"?

The key password inside the keystore differs from the keystore password. Tomcat assumes they are the same. Fix it with `keytool -keypasswd -alias myalias -keystore keystore.p12`, setting the key password to match.

### JKS or PKCS#12?

PKCS#12. It has been the Java default since version 9, keytool warns about JKS on every use, and OpenSSL can read PKCS#12 directly, which makes every later operation easier.

### Does Tomcat reload the certificate without a restart?

Not by default. Some versions support `SSLHostConfig` reload through JMX, but a restart is the reliable route. Plan renewal around that.


## References

- [Tomcat SSL/TLS configuration](https://tomcat.apache.org/tomcat-10.1-doc/ssl-howto.html) — connector attributes for PEM and keystore configurations
- [keytool reference](https://docs.oracle.com/en/java/javase/21/docs/specs/man/keytool.html) — the Java keystore tool and its import options

## Related pages

- https://certguru.io/convert/pem-to-jks/
- https://certguru.io/convert/jks-to-pem/
- https://certguru.io/formats/jks-keystore/
- https://certguru.io/formats/pkcs12-pfx-p12/
- https://certguru.io/platforms/nginx/
- https://certguru.io/concepts/free-tls-certificate/

--
CertGuru — https://certguru.io
