This happens because browsers use the OS trust store, while Java servers use their own cacerts trust store.
1. The Problem
A public API (e.g., a flood-control agency’s HTTPS endpoint) works fine in Chrome or Edge, but fails in a Java server with PKIX path building failed.
2. How HTTPS Trust Works
- The server provides its SSL/TLS certificate plus intermediates.
- The client must validate the chain up to a trusted root CA.
- Clients don’t store every site certificate, only a few dozen to a few hundred root CAs.
3. Browser vs Java
| Environment | Trust Store | Notes |
|---|---|---|
| Browsers (Vue web apps) | OS trust store | Updated with OS patches |
| Flutter apps | Android/iOS trust store | Uses the mobile OS certs |
| Java servers | cacerts |
Shipped with JDK; may miss local/rare CAs |
4. Why Did It Fail?
The API server’s root CA was not in Java’s cacerts. Browsers worked because the OS store already included it, but Java needed a manual import.
5. Fix
# Inspect the server certificate chain
openssl s_client -connect api.example.gov:443 -showcerts
# Save the needed root/intermediate CA, then import
keytool -importcert -file RootCA.crt -alias rootca \
-keystore $JAVA_HOME/lib/security/cacerts -storepass changeit
For production, prefer a dedicated truststore and configure it via JVM options:
java -Djavax.net.ssl.trustStore=/path/to/truststore.jks \
-Djavax.net.ssl.trustStorePassword=yourpass \
-jar app.jar
6. FAQ
Q. Is JDK only from Oracle?
No. There are OpenJDK, Temurin, Corretto, Zulu, Red Hat builds, etc.
Q. Are there billions of root CAs?
No. Just dozens to a few hundred. All site certs chain up to them.
Q. Do Vue/Flutter need extra CA setup?
Usually no. They rely on the browser or mobile OS trust store.