- JAVA
PKIX path building failedの原因と直し方|Java証明書
「PKIX path building failed: unable to find valid certification path to requested target」は、接続先のサーバー証明書から、Java が信頼している認証局(ルート証明書)までの「証明書の鎖」をたどれなかったときに出るエラーです。 Java は、OSやブラウザとは別の信頼ストア(cacerts)を持っているため、「ブラウザでは開けるのに Java からだけつながらない」ことがよく起きます。
原因は次の3つでほぼ説明できます。
- 自己署名証明書や社内の認証局の証明書で、Java の信頼ストアに入っていない
- サーバーが中間証明書を送っていない(ブラウザは補完してくれるが、Java は補完しない)
- 社内プロキシ・セキュリティ製品がTLSを検査している(通信の途中で証明書が差し替わる)
この記事では3つとも実際に起こし、出たメッセージと直し方を並べました。証明書の検証を無効にする書き方は載せていません。通信の盗み見や改ざんを防げなくなるためです。
確認環境:Ubuntu 24.04、OpenJDK 21.0.10(java.net.http.HttpClient)、keytool、OpenSSL 3.0.13。テスト用の認証局(ルート→中間→サーバー)を作り、Python の HTTPS サーバーで証明書の送り方を変えて確認しました(確認日 2026年10月10日)。
エラー文で原因を分ける
エラー文(SSLHandshakeException の後ろ) |
意味 | 原因と直し方 |
|---|---|---|
PKIX path building failed: ... unable to find valid certification path to requested target |
信頼できる認証局までたどれない | この記事の本題。例1〜3 |
PKIX path validation failed: ... validity check failed(certificate_expired) |
鎖はたどれたが、有効期限が切れている | サーバー証明書の更新。PCの時計のずれも確認 |
No subject alternative DNS name matching localhost found. |
証明書のホスト名とURLが違う | URLのホスト名を証明書に合わせる。証明書の SAN を確認 |
No subject alternative names matching IP address 127.0.0.1 found |
IPアドレスで接続したが、証明書に IP が入っていない | ホスト名で接続する。IPで使うなら SAN に IP を入れて発行 |
下の2つは、同じ SSLHandshakeException でも原因が別です。PKIX path building failed なら、信頼ストアと証明書の鎖を調べます。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「PKIX path building failedの原因と直し方|Java証明書」
まず接続先の証明書を見る
keytool -printcert -sslserver で、サーバーが送ってくる証明書の鎖を確認できます(Java に付いているコマンドなので、追加のインストールは要りません)。
$ keytool -printcert -sslserver localhost:8442
Certificate #0
Owner: CN=localhost
Issuer: CN=Demo Intermediate CA
Valid from: Fri Oct 09 20:59:46 JST 2026 until: Thu Nov 11 20:59:46 JST 2027
| 見るところ | 分かること |
|---|---|
Certificate # がいくつあるか |
#0 だけなら、中間証明書を送っていない可能性(例2) |
最後の証明書の Issuer |
どの認証局を信頼すればよいか。社名や製品名が出たらプロキシの可能性(例3) |
Owner と Issuer が同じ |
自己署名証明書(例1) |
Valid from ... until |
有効期限 |
OpenSSL が使える環境なら、openssl s_client -connect ホスト:443 -servername ホスト -showcerts でも同じことが分かります。
例1:自己署名証明書・社内の認証局
$ java Get https://localhost:8441/
Exception in thread "main" javax.net.ssl.SSLHandshakeException: (certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:960)
...
開発環境のサーバー、社内システム、検証用のAPIなどで、公的な認証局ではない証明書を使っていると出ます。直し方は、その証明書(社内の認証局ならルート証明書)を Java の信頼ストアに取り込むことです。
直し方A:自分の信頼ストアを作って指定する
keytool -importcert -noprompt -alias demo-root -file root.crt \
-keystore trust.p12 -storepass changeit
java -Djavax.net.ssl.trustStore=trust.p12 -Djavax.net.ssl.trustStorePassword=changeit -cp . Get https://localhost:8443/
Certificate was added to keystore
HTTP 200
ただし、-Djavax.net.ssl.trustStore を指定すると、Java 標準の cacerts は使われなくなります。 上の trust.p12 のまま公開サイト(GitHub)に接続すると、今度は公開サイトで同じエラーになりました。
$ java -Djavax.net.ssl.trustStore=trust.p12 ... Get https://github.com/
Exception in thread "main" javax.net.ssl.SSLHandshakeException: (certificate_unknown) PKIX path building failed: ...
社内と社外の両方に接続するアプリでは、cacerts をコピーしてから社内の証明書を足すのが安全です。
cp "$JAVA_HOME/lib/security/cacerts" mytrust.p12
keytool -importcert -noprompt -alias corp-root -file corp-root.crt -keystore mytrust.p12 -storepass changeit
直し方B:Java 標準の cacerts に取り込む
keytool -importcert -noprompt -alias corp-root -file corp-root.crt -cacerts -storepass changeit
| 項目 | 内容 |
|---|---|
-cacerts |
Java 標準の cacerts を指す(Java 9 以降)。Java 8 は -keystore "$JAVA_HOME/jre/lib/security/cacerts" |
| パスワード | 初期値は changeit |
| 権限 | 書き込みに管理者権限が要る(Windows は管理者のコマンドプロンプト、Linux・macOS は sudo) |
| 注意 | Java をアップデート・入れ替えると、取り込んだ証明書は消える |
Ubuntu・Debian の OpenJDK は、cacerts が /etc/ssl/certs/java/cacerts へのリンクになっています。この場合は、OS の証明書の仕組みに入れると Java にも反映され、Java のアップデートでも消えません。
sudo cp demo-root.crt /usr/local/share/ca-certificates/demo-root.crt
sudo update-ca-certificates
Adding debian:demo-root.pem
done.
確認環境で、この方法で取り込んだ後に HTTP 200 になることを確かめました。外すときは、.crt を消して update-ca-certificates --fresh を実行しても Java の cacerts には残っていたため、keytool -delete -alias debian:demo-root.pem -cacerts も合わせて実行しました。
例2:サーバーが中間証明書を送っていない
ルート証明書を信頼ストアに入れているのに、エラーになる場合があります。
$ keytool -printcert -sslserver localhost:8442 ← 中間証明書を送らないサーバー
Certificate #0
Owner: CN=localhost
Issuer: CN=Demo Intermediate CA
$ java -Djavax.net.ssl.trustStore=trust.p12 ... Get https://localhost:8442/
Exception in thread "main" javax.net.ssl.SSLHandshakeException: (certificate_unknown) PKIX path building failed: ...
$ keytool -printcert -sslserver localhost:8443 ← 中間証明書も送るサーバー
Certificate #0
Owner: CN=localhost
Issuer: CN=Demo Intermediate CA
Certificate #1
Owner: CN=Demo Intermediate CA
Issuer: CN=Demo Root CA
$ java -Djavax.net.ssl.trustStore=trust.p12 ... Get https://localhost:8443/
HTTP 200
サーバー証明書(#0)→中間証明書(#1)→ルート証明書(信頼ストア)とつながって初めて検証が通ります。#1 が無いと、Java は「Demo Intermediate CA」が何者か分からず、ルートまでたどれません。
ブラウザは、証明書の中に書かれた取得先から中間証明書を自動で取りにいったり、以前に見た中間証明書を覚えていたりするため、この状態でも開けてしまいます。「ブラウザでは開けるのに Java だけエラー」の多くは、このパターンです。
| 直し方 | 内容 |
|---|---|
| サーバー側で直す(本来の直し方) | サーバーの設定で、サーバー証明書と中間証明書をつなげたファイル(fullchain)を指定する。nginx は ssl_certificate に fullchain.pem、Apache 2.4.8 以降は SSLCertificateFile に中間証明書も含めたファイル |
| クライアント側で補う | 中間証明書を信頼ストアに取り込む。確認環境では、中間証明書だけを入れた信頼ストアで HTTP 200 になった。ただし中間証明書は更新が早いので、サーバー側で直すまでのつなぎにとどめる |
例3:社内プロキシ・セキュリティ製品のTLS検査
会社のネットワークでは、プロキシやセキュリティ製品が HTTPS の通信を検査していることがあります。この場合、接続先から届く証明書はプロキシが作り直したもので、発行元はプロキシ(または会社)の認証局です。
確認環境もTLSを検査するプロキシを通る構成だったため、公開の認証局だけを入れた信頼ストアで GitHub に接続すると、同じエラーになりました。プロキシの認証局を足すと通りました。
--- 公開の認証局だけの信頼ストア
Exception in thread "main" javax.net.ssl.SSLHandshakeException: (certificate_unknown) PKIX path building failed: ...
--- 公開の認証局+プロキシの認証局
HTTP 200
| 確認すること | 方法 |
|---|---|
| プロキシが検査しているか | keytool -printcert -sslserver github.com:443 の最後の Issuer が、公開の認証局ではなく会社名・製品名になっている |
| プロキシの認証局の証明書 | 情報システム部門から配布されているものを使う。Windows では「証明書の管理」の「信頼されたルート証明機関」に入っていることが多い |
| 取り込み先 | 例1の直し方A(cacerts のコピーに足す)か B |
Windows では、Java に Windows の証明書ストアを使わせる方法もあります。会社の認証局が Windows に配布済みなら、取り込みの作業が要りません。
java -Djavax.net.ssl.trustStoreType=Windows-ROOT -jar app.jar
どの信頼ストアが使われているかを確かめる
取り込んだのに直らないときは、別の Java(別の cacerts)で動いていることがよくあります。-Djavax.net.debug=ssl:trustmanager を付けると、実際に読んだ信頼ストアが表示されます。
$ java -Djavax.net.debug=ssl:trustmanager -cp . Get https://localhost:8441/
javax.net.ssl|DEBUG|...|TrustStoreManager.java:162|Inaccessible trust store: /usr/lib/jvm/java-21-openjdk-amd64/lib/security/jssecacerts
javax.net.ssl|DEBUG|...|TrustStoreManager.java:113|trustStore is: /usr/lib/jvm/java-21-openjdk-amd64/lib/security/cacerts
Java は、javax.net.ssl.trustStore の指定 → jssecacerts → cacerts の順に信頼ストアを探します。上の例では jssecacerts が無いので cacerts を使っています。
| 動かしているもの | 使われる Java | 指定のしかた |
|---|---|---|
コマンドの java |
PATH の先頭の Java |
java -version、where java(Windows)、which java |
| Maven | JAVA_HOME の Java |
MAVEN_OPTS="-Djavax.net.ssl.trustStore=... -Djavax.net.ssl.trustStorePassword=..." |
| Gradle | Gradle を動かす Java(IDEでは設定画面の Gradle JVM) | gradle.properties に systemProp.javax.net.ssl.trustStore=... |
| IntelliJ IDEA・Eclipse | IDE に同梱の Java、またはプロジェクトの JDK | 実行構成の VM オプションに -Djavax.net.ssl.trustStore=... |
| Docker のコンテナ | イメージの中の Java | Dockerfile で cacerts に取り込む、または起動オプションで指定 |
証明書の検証を無効にしない
検索すると、すべての証明書を信頼する TrustManager を作ってエラーを消す書き方が見つかります。これはエラーが消えるだけで、偽のサーバーにも接続してしまう状態です。テスト用に書いたコードが本番に残ることもあるため、この記事では載せていません。開発環境でも、例1の直し方A(自分の信頼ストアを作る)で同じ手間で済みます。
確認の手順(チェックリスト)
| 順番 | 確認すること | コマンド・方法 |
|---|---|---|
| 1 | エラー文が PKIX path building failed か |
期限切れ・ホスト名違いなら別の原因 |
| 2 | サーバーが送る証明書の鎖 | keytool -printcert -sslserver ホスト:443 |
| 3 | 中間証明書が送られているか | Certificate #1 があるか |
| 4 | 最後の発行元(Issuer)は誰か | 自己署名・社内の認証局・プロキシ |
| 5 | どの Java・どの信頼ストアで動いているか | -Djavax.net.debug=ssl:trustmanager |
| 6 | 取り込んだ証明書が入っているか | keytool -list -cacerts -storepass changeit | grep -i 別名 |
よくある質問
Q. ブラウザでは鍵マークが出て正常なのに、Java だけエラーになります。
A. 多いのは2つです。サーバーが中間証明書を送っていない(例2)か、社内の認証局・プロキシの証明書が Windows には入っていても Java の cacerts には入っていない(例1・3)かです。keytool -printcert -sslserver の結果で見分けられます。
Q. 昨日まで動いていたのに、急にエラーになりました。 A. 接続先のサーバー証明書が更新されて、発行元や中間証明書が変わった、または Java をアップデートして取り込んでいた証明書が消えた、というケースが多くあります。会社のネットワークでは、プロキシの設定が変わった可能性もあります。
Q. Spring Boot の RestTemplate・WebClient でも同じ直し方ですか。 A. 同じです。これらも Java の信頼ストアを使うため、JVM の起動オプションで信頼ストアを指定するか、cacerts に取り込みます。
Q. cacerts のパスワードを忘れました。
A. 変更していなければ初期値の changeit です。cacerts の中身は公開の証明書なので、変更していないことが多いです。
まとめ
PKIX path building failedは、信頼できる認証局まで証明書の鎖をたどれないエラー。期限切れ・ホスト名違いとはエラー文で区別できる- まず
keytool -printcert -sslserverで鎖を見る。#0 だけなら中間証明書の不足、発行元が会社名ならプロキシ - 自己署名・社内の認証局は信頼ストアに取り込む。
trustStoreを指定すると cacerts は使われなくなるので、cacerts のコピーに足す - 中間証明書の不足はサーバー側で直すのが本来の直し方。ブラウザは補完するので気づきにくい
- 取り込んでも直らないときは、別の Java で動いている。
-Djavax.net.debug=ssl:trustmanagerで確認する - 証明書の検証を無効にする書き方は使わない
参考・出典
確認日はいずれも 2026年10月10日です。
- Java SE 21「The keytool Command」:https://docs.oracle.com/en/java/javase/21/docs/specs/man/keytool.html
- Java SE 21 Security Developer's Guide「Java Secure Socket Extension (JSSE) Reference Guide」:https://docs.oracle.com/en/java/javase/21/security/java-secure-socket-extension-jsse-reference-guide.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「PKIX path building failedの原因と直し方|Java証明書」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。