Error Sonarqube "PKIX path building failed: unable to find valid certification path to requested"

I have a server running SonarQube in a Docker container, configured using a Docker Compose file. On this server, I also use an SSL certificate issued by a Certificate Authority (CA) with Apache configured as a reverse proxy. However, when performing code analysis through the GitLab CI/CD pipeline, I encounter the error “PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.” How can I validate the certificate to resolve this issue?

Sonarqube version: 10.6.0-community
SonarScanner 5.0.1.3006

Hi,

Welcome to the community!

The docs may help.

 
Ann

Hi Ann,

I followed all the recommendations in the documentation for managing client certificates, but I still haven’t been able to validate my certificate. Could you help me identify what might be missing?

docker-compose.yaml:

services:
sonarqube:
container_name: sonarqube
image: sonarqube:10.6.0-community
environment:
- SONAR_JDBC_URL
- SONAR_JDBC_USERNAME
- SONAR_JDBC_PASSWORD
- SONARQUBE_HOME
- KEYSTORE_PASSWORD=mypassword
- SONARQUBE_JAVA_OPTS=-Djavax.net.ssl.keyStore=/opt/sonarqube/certs/Keystore.jks -Djavax.net.ssl.keyStorePassword=mypassword

volumes:
  - sonarqube_conf:/opt/sonarqube/conf
  - sonarqube_extensions:/opt/sonarqube/extensions
  - sonarqube_logs:/opt/sonarqube/logs
  - sonarqube_data:/opt/sonarqube/data
  - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins
  - ./certs:/opt/sonarqube/certs
  - /etc/ssl/certs/INTERMEDIATE.crt:/opt/sonarqube/certs/INTERMEDIATE.crt:ro
  - /etc/ssl/cert-cecremge/server.pem:/opt/sonarqube/certs/server.pem:ro

.gitlab-ci.yaml:

image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [“”]

variables:
SONAR_USER_HOME: “${CI_PROJECT_DIR}/.sonar”
SONAR_HOST_URL: “https://mydomain.com

sonarqube-check:
stage: sonarqube-check
dependencies:
- build
cache:
policy: pull
key: “${CI_COMMIT_SHORT_SHA}”
paths:
- sonar-scanner/
script:
- export SONAR_SCANNER_OPTS=“-Djavax.net.ssl.keyStore=/opt/sonarqube/certs/KeyStore.jks -Djavax.net.ssl.keyStorePassword=mypassword”
- sonar-scanner -X

Marcos

Hi,

It looks like you’ve provided a keystore, instead of the truststore the docs call for.

 
HTH,
Ann

Hi Ann,

I followed all the recommendations in the documentation for managing client certificates and, as you suggested, made the correction by switching from the key repository to the trusted repository. However, I still haven’t been able to validate the certificate. Could you help me understand what might be missing?

-Djavax.net.ssl.trustStore=/opt/java/openjdk/lib/security/cacerts

Hi,

What’s the error or bad behavior you’re seeing now?

Also, it’s not just the truststore you need to set:

SONAR_SCANNER_OPTS="-Djavax.net.ssl.trustStore=/repositories/tls-mutual-nginx/cacerts -Djavax.net.ssl.trustStorePassword=changeit"

 
HTH,
Ann

Before configuring the trusted storage, I imported the certificates into the key repository:

keytool -importcert -file /opt/sonarqube/certs/INTERMEDIATE.crt -alias intermediate-cert -cacerts -storepass mypassword -trustcacerts -noprompt

keytool -importcert -file /opt/sonarqube/certs/server.pem -alias server-cert -cacerts -storepass mypassword -trustcacerts -noprompt

Here is the error output I am receiving:

sonar-scanner -X

14:49:53.777 DEBUG: Get bootstrap index...
14:49:53.777 DEBUG: Download: [MASKED]/batch/index
14:49:55.469 ERROR: SonarQube server [[MASKED]] can not be reached
14:49:55.470 INFO: ------------------------------------------------------------------------
14:49:55.471 INFO: EXECUTION FAILURE
14:49:55.471 INFO: ------------------------------------------------------------------------
14:49:55.472 INFO: Total time: 2.064s
14:49:55.489 INFO: Final Memory: 4M/24M
14:49:55.489 INFO: ------------------------------------------------------------------------
14:49:55.490 ERROR: Error during SonarScanner execution
org.sonarsource.scanner.api.internal.ScannerException: Unable to execute SonarScanner analysis
	at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.lambda$createLauncher$0(IsolatedLauncherFactory.java:85)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.createLauncher(IsolatedLauncherFactory.java:74)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.createLauncher(IsolatedLauncherFactory.java:70)
	at org.sonarsource.scanner.api.EmbeddedScanner.doStart(EmbeddedScanner.java:185)
	at org.sonarsource.scanner.api.EmbeddedScanner.start(EmbeddedScanner.java:123)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:74)
	at org.sonarsource.scanner.cli.Main.main(Main.java:62)
Caused by: java.lang.IllegalStateException: Fail to get bootstrap index from server
	at org.sonarsource.scanner.api.internal.BootstrapIndexDownloader.getIndex(BootstrapIndexDownloader.java:42)
	at org.sonarsource.scanner.api.internal.JarDownloader.getScannerEngineFiles(JarDownloader.java:58)
	at org.sonarsource.scanner.api.internal.JarDownloader.download(JarDownloader.java:53)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.lambda$createLauncher$0(IsolatedLauncherFactory.java:76)
	... 7 more
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:378)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:316)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1351)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1226)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1169)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:458)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:201)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1510)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1425)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.connectTls(RealConnection.java:336)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.establishProtocol(RealConnection.java:300)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.connect(RealConnection.java:185)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:108)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ExchangeFinder.find(ExchangeFinder.java:88)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.Transmitter.newExchange(Transmitter.java:169)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.RealCall.getResponseWithInterceptorChain(RealCall.java:221)
	at org.sonarsource.scanner.api.internal.shaded.okhttp.RealCall.execute(RealCall.java:81)
	at org.sonarsource.scanner.api.internal.ServerConnection.callUrl(ServerConnection.java:115)
	at org.sonarsource.scanner.api.internal.ServerConnection.downloadString(ServerConnection.java:99)
	at org.sonarsource.scanner.api.internal.BootstrapIndexDownloader.getIndex(BootstrapIndexDownloader.java:39)
	... 10 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
	at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
	at java.base/sun.security.validator.Validator.validate(Validator.java:264)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1335)
	... 44 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:148)
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:129)
	at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
	... 49 more
Cleaning up project directory and file based variables

ERROR: Job failed: exit code 1

Hi,

Can you take a look here? It looks like the docs may be behind:

 
Thx,
Ann

Hi,

After testing the solution you suggested by placing the server certificate in a separate PKCS12 keystore, I am still encountering the same errors.

SONAR_SCANNER_OPTS="-Dsonar.scanner.truststorePath=/opt/sonarqube/certs/truststore.p12 -Dsonar.scanner.truststorePassword=changeit

keytool -importkeystore -srckeystore /opt/sonarqube/certs/truststore.p12 -srcstoretype pkcs12 -destkeystore /opt/java/openjdk/lib/security/cacerts -deststorepass changeit

The documentation also doesn’t seem to provide the correct answer for this issue. What is the proper way to validate my TLS certificate with Sonar Scanner?

Hi,

From that thread I linked to earlier:

 
HTH,
Ann

Hi @Marcos_Vinicius

For your information, we just released a new version of our SonarScanner Docker image (11.1).

Would you mind trying changing your keystore to the PKCS12 format (JKS is deprecated for a while), and moving it to the location that is going to become the standard for all SonarScanners:

.gitlab-ci.yaml:

image:
  name: sonarsource/sonar-scanner-cli:11
  entrypoint: [“”]

variables:
  SONAR_USER_HOME: “${CI_PROJECT_DIR}/.sonar”
  SONAR_HOST_URL: “https://mydomain.com”
  # only needed for SonarQube versions < 10.6
  SONAR_SCANNER_OPTS: "-Djavax.net.ssl.trustStore=${SONAR_USER_HOME}/ssl/truststore.p12 -Djavax.net.ssl.trustStorePassword=mypassword" 

sonarqube-check:
  stage: sonarqube-check
  dependencies:
    - build
  cache:
    policy: pull
    key: “${CI_COMMIT_SHORT_SHA}”
    paths:
      - sonar-scanner/
  script:
    - mv /where/is/your/truststore.p12 $SONAR_USER_HOME/ssl/truststore.p12
    - sonar-scanner -Dsonar.scanner.truststorePasssword=mypassword

For reference, here is a way to produce a PKCS12 truststore from your PEM or DER server certificate:

keytool -noprompt -importcert -storetype PKCS12  -alias testfabrik -keystore $SONAR_USER_HOME/ssl/truststore.p12 -storepass mypassword  -trustcacerts -file /etc/ssl/certs/tf/tf.crt
3 Likes

Hello,

I would like to thank you for your help and let you know that the solution you provided worked perfectly. I will share my .gitlab-ci.yaml file to help others who may face the same issue.

# Job to run SonarQube check
sonarqube-check:
  stage: sonarqube-check
  image:
    name: sonarsource/sonar-scanner-cli:11
    entrypoint: [""]
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"
    SONAR_HOST_URL: "https://my-domain.com.br"
    SONAR_SCANNER_OPTS: "-Dsonar.scanner.truststorePath=${CI_PROJECT_DIR}/storage/certs/truststore.p12 -Dsonar.scanner.truststorePassword=mypassword"
  cache:
    policy: pull
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script: 
    - sonar-scanner -Dsonar.qualitygate.wait=true
  allow_failure: true
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
1 Like

Thanks @Marcos_Vinicius for the follow up. May I ask you to edit your snippet to not suggest to use SONAR_SCANNER_OPTS. This variable is intended for JVM properties (like -Xmx or -Djavax.xxx), and the fact it is also working here is more of a side effect that I prefer not to see widespread.

Please pass the scanner properties directly in the command line:

  script: 
    - sonar-scanner -Dsonar.qualitygate.wait=true -Dsonar.scanner.truststorePath=${CI_PROJECT_DIR}/storage/certs/truststore.p12 -Dsonar.scanner.truststorePassword=mypassword
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.