You need Java to trust a corporate root, lab CA, or TLS intercept certificate. The JDK default truststore is cacerts, and keytool is the standard tool to add entries — but the file location and update mechanism differ between Debian-family and RHEL-family Linux.
This guide shows how to find cacerts on Ubuntu 26.04 (tested live), documents the equivalent paths on Debian, RHEL, and Rocky Linux from official sources, and imports a certificate into a copy of cacerts so you do not break the system bundle. For why a custom truststore is often better than editing the live file, read Custom Java truststore vs cacerts.
Tested on: Ubuntu 26.04 LTS; OpenJDK 25.0.3; kernel 7.0.0-27-generic. RHEL and Rocky paths documented from Red Hat and man-page sources (not live-tested here).
Default cacerts facts
Before you edit anything, confirm these defaults match your JDK package — most Linux OpenJDK builds use the same values:
| Property | Value |
|---|---|
| Keystore type | Check with keytool -list -cacerts -storepass changeit; many Debian-family Java cacerts files report JKS, while new Java keystores default to PKCS12 |
| Default password | changeit (unless your admin or vendor changed it) |
| Entry type after import | trustedCertEntry |
| Import command | keytool -importcert |
Install keytool on Ubuntu (or your distro’s java-*-openjdk-devel package) before running the commands below.
Ubuntu and Debian: locate cacerts
On Debian-family distros, $JAVA_HOME/lib/security/cacerts is usually a symlink to the distro-managed bundle. Resolve the JDK that owns your keytool binary and inspect where it points:
KEYTOOL=$(readlink -f "$(command -v keytool)")
JAVA_HOME=$(dirname "$(dirname "$KEYTOOL")")
ls -la "$JAVA_HOME/lib/security/cacerts"lrwxrwxrwx 1 root root 27 Apr 26 15:14 /usr/lib/jvm/java-25-openjdk-amd64/lib/security/cacerts -> /etc/ssl/certs/java/cacertsThe symlink confirms the JDK reads /etc/ssl/certs/java/cacerts, not a private copy under /usr/lib/jvm.
If several JDK versions are installed, list every cacerts path:
find /usr/lib/jvm -name cacerts/usr/lib/jvm/java-25-openjdk-amd64/lib/security/cacertsEach result should resolve to the same /etc/ssl/certs/java/cacerts file on a single-JDK host. The real file is owned by the ca-certificates-java package, so package upgrades can refresh it from the distro CA bundle.
RHEL and Rocky Linux: locate cacerts (documented)
On RHEL-family systems, Java trusts the system-wide store at /etc/pki/java/cacerts, maintained by update-ca-trust. Typical OpenJDK packages expose it through a symlink:
/usr/lib/jvm/java-<version>/lib/security/cacerts -> /etc/pki/java/cacertsExact JDK directory names vary (java-17-openjdk, java-21-openjdk, etc.). After installing OpenJDK, confirm the canonical path and any JVM symlinks:
find /usr/lib/jvm -name cacerts 2>/dev/null
ls -la /etc/pki/java/cacertsYou should see /etc/pki/java/cacerts as a regular file (not a broken symlink) and one or more JDK paths pointing at it. Red Hat build of OpenJDK documentation references /etc/pki/java/cacerts as the global trust anchor repository. For CAs that every Java app on the host should trust, copy PEM files to /etc/pki/ca-trust/source/anchors/ and run update-ca-trust extract instead of manual keytool edits on the live file.
Safe lab import: copy cacerts first
/etc/ssl/certs/java/cacerts or /etc/pki/java/cacerts directly normally requires root and affects all JVMs that read that file. Back it up and prefer distro trust tools or a custom truststore.
Never practice on the production symlink target without a backup. Work on a copy so a typo cannot break every JVM app on the host:
mkdir -p ~/cacerts-lab
cd ~/cacerts-lab
cp /etc/ssl/certs/java/cacerts cacerts-copycacerts-copy is a private truststore file you can delete when the lab ends. On this tested Ubuntu host, keytool -list reports Keystore type: JKS.
Import a PEM-encoded root CA with -importcert (replace root-ca.crt with your file):
keytool -importcert -alias labroot-test -file root-ca.crt \
-keystore cacerts-copy -storepass changeit -nopromptCertificate was added to keystorekeytool stored the CA as a trustedCertEntry under alias labroot-test.
Confirm the new entry and note the SHA-256 fingerprint for your change ticket:
keytool -list -alias labroot-test -keystore cacerts-copy -storepass changeitlabroot-test, Jul 2, 2026, trustedCertEntry,
Certificate fingerprint (SHA-256): FF:AB:35:9A:78:4D:E2:E9:3E:44:33:D0:05:42:E2:2A:C3:9E:5E:79:EB:88:23:DE:9C:7F:17:3F:8F:74:30:7AThe entry type trustedCertEntry confirms this is a trust anchor, not a private key.
Remove the test entry from your copy when the lab ends:
keytool -delete -alias labroot-test \
-keystore cacerts-copy \
-storepass changeit -nopromptSee Change alias, password, delete for more keystore maintenance commands.
Point one JVM at your copy instead of the system file. Use the store type reported by keytool -list -keystore cacerts-copy; on this tested Ubuntu host it was JKS:
java -Djavax.net.ssl.trustStore=$HOME/cacerts-lab/cacerts-copy \
-Djavax.net.ssl.trustStorePassword=changeit \
-Djavax.net.ssl.trustStoreType=JKS \
-jar your-app.jarOnly this process loads cacerts-copy; other Java apps on the host keep using the untouched system bundle.
Compare entry count with the untouched system file:
keytool -list -cacerts -storepass changeit | head -6Keystore type: JKS
Keystore provider: SUN
Your keystore contains 121 entries
debian:ac_raiz_fnmt-rcm.pem, Jul 2, 2026, trustedCertEntry,The system store on this host held 121 public CAs. Your copy should report one additional entry after import.
Import methods by distro goal
Pick the path that matches how widely the CA must be trusted — one app, every Java process on the host, or a quick local test:
| Goal | Ubuntu / Debian | RHEL / Rocky Linux |
|---|---|---|
| One Java app trusts a private CA | Custom trust.p12 + javax.net.ssl.trustStore |
Same |
| All Java apps on the host | update-ca-certificates / ca-certificates-java refresh |
update-ca-trust extract |
| Quick local experiment | Copy cacerts, keytool -importcert on copy |
Copy /etc/pki/java/cacerts, import on copy |
| Remove a bad import | Restore from package: sudo apt install --reinstall ca-certificates-java |
update-ca-trust extract after removing anchor PEM |
Ubuntu/Debian host-wide CA trust
For Ubuntu/Debian host-wide CA trust, place a PEM certificate with a .crt extension under /usr/local/share/ca-certificates/ and run:
sudo cp corp-root.crt /usr/local/share/ca-certificates/
sudo update-ca-certificatesThis updates the OS trust store. With ca-certificates-java installed, Debian-family systems can also refresh the Java truststore through package hooks, but verify /etc/ssl/certs/java/cacerts afterward with keytool -list -cacerts -storepass changeit.
/etc/ssl/certs/java/cacerts path exists or is shared. Use the image's JDK path, build a custom truststore into the image, or mount one at runtime. See Java truststore in Docker and Kubernetes.
Common errors
These messages appear most often when importing into cacerts or a copy of it:
| Error | Cause | Fix |
|---|---|---|
Public keys in reply and keystore don't match |
Importing a signed leaf onto wrong alias | Use -importcert for CA certs only in cacerts; see public keys mismatch fix |
keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect |
Wrong -storepass |
Default is changeit unless your admin changed it |
Certificate not imported, alias <name> already exists |
Duplicate alias | Pick a unique -alias or delete the old entry with keytool -delete |
| Import succeeds but app still fails PKIX | JVM not using your modified store | Set -Djavax.net.ssl.trustStore to the file you edited |
Production checklist
Before you edit a live trust bundle on a shared host, walk through this list:
- Prefer a dedicated PKCS12 truststore over editing live
cacerts— custom truststore guide. - Use descriptive aliases (
corp-root-2026, notcert1). - Document SHA-256 fingerprints in your change ticket.
- On RHEL/Rocky, use
update-ca-trustfor host-wide CAs. - On Ubuntu/Debian, let
ca-certificates-javamanage public CAs; add private CAs via custom truststore or/usr/local/share/ca-certificates/+update-ca-certificates. - Restart long-running JVM processes after truststore changes.
References
- keytool documentation (Oracle)
- Debian ca-certificates-java package
- Red Hat build of OpenJDK — trust anchor repository
- update-ca-trust(8) man page
- Install keytool on Ubuntu
- keytool cheatsheet
- Fix Java PKIX path building failed
Summary
Java cacerts on Ubuntu and Debian lives at /etc/ssl/certs/java/cacerts, symlinked from $JAVA_HOME/lib/security/cacerts, with default password changeit. On RHEL and Rocky Linux the system file is /etc/pki/java/cacerts, exposed under /usr/lib/jvm/java-*/lib/security/cacerts. On the tested Ubuntu host, the distro cacerts file reports Keystore type: JKS. Import CAs with keytool -importcert -alias NAME -file cert.crt -keystore cacerts-copy -storepass changeit -noprompt on a copy first, then point your app with -Djavax.net.ssl.trustStore and matching -Djavax.net.ssl.trustStoreType. For production, favor a custom truststore, update-ca-certificates on Debian-family hosts, or update-ca-trust on RHEL-family hosts over editing the global bundle.

