Ошибка PKIX path building failed: unable to find valid certification path to requested target означает, что Java не смогла построить доверенную цепочку сертификата сервера. Для исправления я сначала проверяю сертификаты и фактическую Java процесса, затем добавляю нужный доверенный сертификат в используемое хранилище. Отключать проверку TLS для этого не требуется. Механизм выбора хранилища описан в JSSE Reference Guide для Java 21.

Сертификаты и полную присланную сервером цепочку можно получить по инструкции «Скачать сертификат сайта». Скачивание сертификата само по себе не удостоверяет его подлинность: перед добавлением доверия нужно сверить SHA-256 с владельцем инфраструктуры или другим доверенным источником. Особенно это важно для корневого CA, доверие к которому распространяется на выданные им сертификаты. Предупреждения keytool об импорте доверенных сертификатов.

Импорт в существующее хранилище

Сначала нужно определить JDK именно того процесса, который соединяется с сервером. В IntelliJ IDEA для сборки это Settings → Build, Execution, Deployment → Build Tools → Gradle → Gradle JVM, а путь зарегистрированного JDK виден в Project Structure → SDKs. Project SDK, Java терминала и Java Gradle могут отличаться.

Команда импорта через keytool:

keytool -importcert -file cert_name.crt -keystore keystore_path -alias alias_cert

Где

  • cert_name.crt - имя сертификата; расширение само по себе не определяет формат
  • keystore_path - путь до хранилища сертификатов в JVM
    • Пример: jdk_path/lib/security/cacerts
  • alias_cert - алиас для сертификата

Пароль вводится по запросу; стандартный пароль поставляемого JDK cacerts часто равен changeit, но его могли изменить. -storepass позволяет передать пароль явно. Параметр -noprompt из старого примера убран: при первом добавлении доверия полезно проверить данные сертификата и подтвердить импорт вручную. Параметры keytool.

Проверка, что сертификат был добавлен:

keytool -list -keystore keystore_path -alias alias_cert

Для подробностей и SHA-256 добавить -v. Успех — запись с ожидаемым alias, типом trustedCertEntry и нужным отпечатком, а не только отсутствие запроса пароля.

Пользовательское хранилище без прав администратора

Если JDK установлен в защищённый каталог, например Program Files, обычный пользователь не сможет записать его lib/security/cacerts. Для Gradle можно скопировать стандартное хранилище в доступную папку, добавить сертификаты в копию и явно выбрать её. Копирование сохраняет стандартные доверенные CA, которые нужны для других HTTPS-ресурсов; созданное с нуля хранилище их не содержит. Java поддерживает выбор отдельного файла через javax.net.ssl.trustStore. JSSE: настройка truststore.

Пример для Git Bash в Windows

Все пути ниже учебные: JDK и пользовательский каталог нужно заменить фактическими. cp -i спрашивает перед перезаписью: существующее настроенное хранилище не следует заменять свежей копией без проверки.

cp -i "/c/Program Files/Java/jdk-21/lib/security/cacerts" "$HOME/.gradle/custom-cacerts"
"/c/Program Files/Java/jdk-21/bin/keytool.exe" -importcert -file "$HOME/Downloads/corporate-root.crt" -keystore "$HOME/.gradle/custom-cacerts" -alias "corporate-root"
"/c/Program Files/Java/jdk-21/bin/keytool.exe" -list -v -keystore "$HOME/.gradle/custom-cacerts" -alias "corporate-root"

При ошибке Access denied / Отказано в доступе после сообщения Certificate was added to keystore запись на диск не считается успешной. Итоговую проверку нужно выполнить отдельным -list по тому же файлу.

Подключение к Gradle

В Gradle user home, указанном в IDEA, открыть или создать gradle.properties. По умолчанию это пользовательский каталог .gradle. Существующие настройки сохранить; повторяющиеся ключи не добавлять. Для учебного пользователя developer:

systemProp.javax.net.ssl.trustStore=C:/Users/developer/.gradle/custom-cacerts
systemProp.javax.net.ssl.trustStorePassword=changeit

Это файл gradle.properties, а не gradle.properties.txt: в Windows нужно проверить расширение. Для пути внутри properties использую прямые слеши; обратные слеши в Java properties требуют экранирования. trustStorePassword передаёт существующий пароль хранилища, а не устанавливает новый. changeit здесь относится только к копии стандартного cacerts, а не к учётным данным сервера. Поддержка systemProp.* и расположение пользовательского файла описаны в Gradle Build Environment.

После изменения хранилища или его параметров нужно перезапустить использующую его Java. Для IDEA: закрыть приложение, остановить Gradle daemon и открыть IDEA заново. Команда зависит от оболочки и фактического пути установленного Gradle:

# Git Bash
"/c/tools/gradle/bin/gradle.bat" --stop
# PowerShell, в том числе внутри терминала IDEA
& "C:\tools\gradle\bin\gradle.bat" --stop

Затем выполнить Reload All Gradle Projects. Старый daemon может сохранять SSL-состояние; Gradle относит параметры truststore к неизменяемым свойствам JVM daemon. Выходить из Windows для обычного изменения truststore не требуется.

Если PKIX остался

  1. Проверить alias и SHA-256 в том самом пользовательском файле через keytool -list -v. Проверка другого JDK или другого cacerts не подтверждает настройку сборки.
  2. Проверить фактический Gradle user home, точное имя gradle.properties и путь truststore. Для отделения ошибки файла настроек от ошибки сертификатов можно передать параметры явно при узком запуске help из корня сервиса:
& "C:\tools\gradle\bin\gradle.bat" "-Djavax.net.ssl.trustStore=C:/Users/developer/.gradle/custom-cacerts" "-Djavax.net.ssl.trustStorePassword=changeit" help --no-daemon

help конфигурирует сборку и может компилировать buildSrc и скачивать зависимости; это не проверка полной сборки и не запуск сервиса. Init-скрипты и плагины всё равно выполняются при конфигурации.

  1. Сравнить subject, issuer, серийный номер и SHA-256 импортированного сертификата с сертификатом соединения. Браузер, keytool -printcert -sslserver и OpenSSL могут получить разные сертификаты; конкретный сетевой путь или TLS-перехват нельзя объявлять причиной без отдельного подтверждения. Получение и сравнение цепочки.
  2. Проверить каждый hostname из ошибки. У публичного прокси зависимостей и внутреннего Nexus могут быть разные цепочки. Исправление TLS одного сервера не подтверждает второй.
  3. Проверить промежуточные CA. Сервер может прислать только сертификат сайта; наличие одного корневого CA тогда не гарантирует построения цепочки. Предпочтительно исправить серверную цепочку или получить проверенный комплект CA у администратора. Если в локальное хранилище добавляются промежуточные сертификаты как trustedCertEntry, они тоже становятся доверенными точками, что шире простой передачи недостающей части цепочки. Java PKIX Trust Anchors.

Для диагностики уже воспроизводимой ошибки можно сохранить SSL-лог в PowerShell:

& "C:\tools\gradle\bin\gradle.bat" "-Djavax.net.ssl.trustStore=C:/Users/developer/.gradle/custom-cacerts" "-Djavax.net.ssl.trustStorePassword=changeit" "-Djavax.net.debug=ssl,trustmanager" help --no-daemon *> "$env:TEMP\gradle-tls.log"
Select-String -Path "$env:TEMP\gradle-tls.log" -Pattern "trustStore|TrustStoreManager|adding as trusted|subject|issuer" -Context 2,2

Не все реализации и пути загрузки выводят одинаковые строки о truststore. Пустой результат одного шаблона поиска не доказывает, что диагностика не включилась или файл не загрузился. TLS-лог может содержать внутренние имена, пути и сертификаты: перед передачей нужно выбрать и обезличить нужные фрагменты. Поддержка javax.net.debug описана в JSSE.

Ошибки, которые нужно различать

ОшибкаЧто проверять дальше
HTTP 503 при загрузке дистрибутива GradleДоступность источника дистрибутива; это ещё не ошибка зависимостей
no repositories are definedРепозитории именно проблемной сборки, включая отдельный buildSrc, и корпоративный init-скрипт
PKIX path building failedХранилище, реальный сертификат соединения и полноту цепочки
Username must not be null!Источник credentials: переменные окружения или иная конфигурация init-скрипта; это ещё не ответ сервера о неверном пароле
Не найден плагин, в координатах пустая версияСначала загрузку BOM, задающего версии; не подставлять версии наугад

Корпоративный init.gradle, если используется, должен соответствовать окружению и получать нужные параметры сборочного сервера. Его имя или расположение в GitLab не подтверждают правильность адресов, credentials и внешних загрузок. Стандартные места подключения описаны в Gradle Init Scripts.

Исправление прежней инструкции

16.10.2026: прежнее утверждение «потребуется выход из операционной системы» заменено перезапуском процессов, использующих truststore. Добавлены отдельное пользовательское хранилище, проверка результата записи и диагностика цепочки. Общий способ применён на Windows с JDK 21 и Gradle 8.13; после добавления недостающих промежуточных CA локальная сборка заработала. Это не проверка всех JDK, оболочек и серверных конфигураций.