SonarQube can't download values.protobuf file

Hello everyone,
I’m trying to setup SonarQube pipeline in Azure DevOps server to scan code from a repository and publish it to SonarQube.

The version I’m using is: Community Edition, version 10.8
Deployment type: with Helm in a K8 cluster
Pipeline Agent: Self-Hosted Windows Server

I’m trying to trigger the basic pipeline that SonarQube suggests after creating a new project. I’ve downloaded the necessary extension, configured the service connection and used the relevant tasks: SonarQubePrepare@7, SonarQubeAnalyze@7, SonarQubePublish@7.

The necessary certificates for the Azure DevOps Server are added to the SonarQube java trust store via the CaCerts argument in the values.yaml file of the Helm chart. When I try to run the pipeline I get the following error:
javax.net.ssl.SSLHandshakeException: None of the TrustManagers trust this certificate chain
I’ve added sonar’s certificate chain manually to the java jre that the SonarQubeAnalyze@7 task uses to connect from the agent to the SonarQube Server. I also enabled sonar.verbose=true in the extra properties of the SonarQubePrepare@7 task to get more detailed logs.
When I did that I saw that some requests to the server actually go through:

11:44:42.217 DEBUG --> GET https://sonarqube.my-company.com/api/v2/analysis/version
11:44:42.491 DEBUG <-- 200 https://sonarqube.my-company.com/api/v2/analysis/version (273ms, 14-byte body)
11:44:42.494 INFO  JRE provisioning: os[windows], arch[amd64]
11:44:42.497 DEBUG --> GET https://sonarqube.my-company.com/api/v2/analysis/jres?os=windows&arch=amd64
11:44:42.531 DEBUG <-- 200 https://sonarqube.my-company.com/api/v2/analysis/jres?os=windows&arch=amd64 (33ms, unknown-length body)
...
11:44:43.529 DEBUG --> GET https://sonarqube.my-company.com/api/v2/analysis/engine
11:44:43.647 DEBUG <-- 200 https://sonarqube.my-company.com/api/v2/analysis/engine (117ms, unknown-length body)
11:44:43.656 DEBUG Download https://sonarqube.my-company.com/api/v2/analysis/engine to C:\<path on agent>
11:44:43.656 DEBUG --> GET https://sonarqube.my-company.com/api/v2/analysis/engine
11:44:43.710 DEBUG <-- 200 https://sonarqube.my-company.com/api/v2/analysis/engine

But when the task decides to download the values.protobuf file I get this error in the same log:

11:44:48.329 DEBUG --> GET https://sonarqube.my-company.com/api/settings/values.protobuf
11:44:48.614 DEBUG <-- HTTP FAILED: javax.net.ssl.SSLHandshakeException: None of the TrustManagers trust this certificate chain

I logged on to the agent to try to make the query from the agent’s browser and I got HTTP 401 error. But after that I logged in to the SonarQube Server from the agent and ran the query in the browser again (with me being logged into SonarQube) and the file was downloaded successfully.

This is the pipeline I used:

steps:
- task: SonarQubePrepare@7
  inputs:
    SonarQube: '<my-service-connection>'
    scannerMode: 'cli'
    configMode: 'manual'
    cliProjectKey: '<my-project-key>'
    cliProjectName: '<my-project-name>'
    cliSources: '.'
    extraProperties: |
      # Additional properties that will be passed to the scanner, 
      # Put one key=value per line, example:
      # sonar.exclusions=**/*.bin
      sonar.verbose=true

- task: SonarQubeAnalyze@7
  inputs:
    jdkversion: 'JAVA_HOME_17_X64'

- task: SonarQubePublish@7
  inputs:
    pollingTimeoutSec: '300'

So what seems to be the problem with the pipeline then? Am I missing some configuration in it?

Hey @qaz

With @7 of the SonarQube tasks, there are two JREs at play.

  • One handling the download of the JRE on SonarQube (to support JRE auto-provisioning, basically to make things easier on users when someday we decide the minimum version of Java to run analysis should be Java 21)
  • The JRE that is being downloaded from SonarQube, that actually runs the analysis (and handles further communication with SonarQube).

It seems like certs are working for the first JRE, but not the second.

You can disable JRE auto-provisioning (sonar.scanner.skipJreProvisioning=true) so that the first JRE handles everything.

Or you can make sure the right certs get passed to the second JRE (see the analysis parameters here).

We are aware this isn’t great and hopefully will make this smoother soon.

Hello,

Happy New Year and thank you for your recommendations I’ve tried both ways but from what I gathered from the logs it seem to be some kind of an authentication error.

This is how I configured the tasks:

- task: SonarQubePrepare@7
  inputs:
    SonarQube: '<my-service-connection>'
    scannerMode: 'cli'
    configMode: 'manual'
    cliProjectKey: '<my-project-key>'
    cliProjectName: '<my-project-name>'
    cliSources: '.'
    extraProperties: |
      # Additional properties that will be passed to the scanner, 
      # Put one key=value per line, example:
      # sonar.exclusions=**/*.bin
      sonar.verbose=true
      sonar.scanner.skipJreProvisioning=true
      sonar.scanner.truststorePath=path\to\Java\jdk-17\lib\security\cacerts
      sonar.scanner.truststorePassword=password-for-truststore

- task: SonarQubeAnalyze@7
  inputs:
    jdkversion: 'JAVA_HOME_17_X64'

- task: SonarQubePublish@7
  inputs:
    pollingTimeoutSec: '300'

I’ve tried both options separately and together and it doesn’t seem to work however from all the executions of the pipeline I get a similar type of error (also tried switching between JAVA_HOME_17_X64 and JAVA_HOME_21_X64):

09:14:16.924 DEBUG --> GET https://sonarqube.mycompany.com/api/v2/analysis/version
09:14:17.155 DEBUG <-- 401 https://sonarqube.mycompany.com/api/v2/analysis/version (230ms, 0-byte body)
09:14:17.156 DEBUG --> GET https://sonarqube.mycompany.com/api/server/version
09:14:17.161 DEBUG <-- 200 https://sonarqube.mycompany.com/api/server/version (5ms, 14-byte body)
09:14:17.166 INFO  JRE provisioning is disabled
09:14:17.167 INFO  Using the java executable 'path-to\Java\jdk-17\bin\java.exe' from JAVA_HOME
09:14:17.169 DEBUG Executing: path-to\Java\jdk-17\bin\java.exe --version
09:14:17.287 DEBUG java 17.0.10 2024-01-16 LTS
09:14:17.287 DEBUG Java(TM) SE Runtime Environment (build 17.0.10+11-LTS-240)
09:14:17.287 DEBUG Java HotSpot(TM) 64-Bit Server VM (build 17.0.10+11-LTS-240, mixed mode, sharing)
09:14:17.313 DEBUG --> GET https://sonarqube.mycompany.com/api/v2/analysis/engine
09:14:17.322 DEBUG <-- 401 https://sonarqube.mycompany.com/api/v2/analysis/engine (8ms, 0-byte body)
09:14:17.323 INFO  EXECUTION FAILURE
09:14:17.324 INFO  Total time: 1.722s
##[error]09:14:17.324 ERROR Error during SonarScanner CLI execution
java.lang.IllegalStateException: Error status returned by url [https://sonarqube.mycompany.com/api/v2/analysis/engine]: 401

I’ve encountered the same problem as before. When I try to query the URLs that return error 401 from the agent. It says there is an HTTP error, but when I log in to the SonarQube Server from the agent and then query those same URLs again, valid values are returned. Is there some problem with the configuration options I’m using?

Thanks for the details about what you’ve tried! It seems like you’ve moved passed the cert error. Now I would reckon that the token specified in the service connection here:

Does not have Execute Analysis permissions.

I would suggest you generate a new token that you’re sure has the right permissions and adjust the connection in Azure DevOps.

You can test this token outside of Azure DevOps by using the token in a simple request from the command line.

colin@MAC-L0251 macosx-universal-64 % curl -u squ_restoftokenhere: 'http://localhost:9000/api/v2/analysis/engine' -v
* Host localhost:9000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:9000...
* Connected to localhost (::1) port 9000
* Server auth using Basic with user 'squ_restoftokenhere'
> GET /api/v2/analysis/engine HTTP/1.1
> Host: localhost:9000
> Authorization: Basic c3F1Xzk3ZDUzNzI2ZDcxZWEzOGZhYWQ0MDYwZGU3NDZkODE3MDQ0MGMxN2U6
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 0
< X-Content-Type-Options: nosniff
< Content-Security-Policy: default-src 'self'; base-uri 'none'; connect-src 'self' http: https:; font-src 'self' data:; img-src * data: blob:; object-src 'none'; script-src 'self' 'sha256-D1jaqcDDM2TM2STrzE42NNqyKR9PlptcHDe6tyaBcuM='; style-src 'self' 'unsafe-inline'; worker-src 'none'
< SonarQube-Authentication-Token-Expiration: 2025-02-01T01:00:00+0100
< vary: accept-encoding
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Thu, 02 Jan 2025 09:55:37 GMT
< 
* Connection #0 to host localhost left intact
{"filename":"scanner-datacenter-10.8.0.100206-all.jar","sha256":"1ed2e3b5d29406c0cf897e2e3dd1aff7bf37ecd7e154d3b94db1bb75ecce1b64"}%

Hello Colin,

Thank you for your terrific support! The issue has been resolved. Turns out the token has expired a few days before this conversation. I’ve reissued the token with the necessary permissions and now the pipeline functions properly and the results get published to the SonarQube Server Dashboard. I’m able to see every issue, security hotspot etc. I will just shortly summarize what I’ve done to resolve this issue here in case someone encounters the same problem and mark it as a solution.

  1. Set the sonar.scanner.skipJreProvisioning=true
  2. Set sonar.scanner.truststorePath and sonar.scanner.truststorePassword to the truststore that contains the certificates for your Azure DevOps server (the whole certificate chain)
  3. Make sure the token you’ve provided for the Service Connection has the necessary permission to perform analysis on your code.
1 Like

For what it’s worth, I think you can skip #2 if you do #1.

Since from the beginning, the JRE that kicked off the scanner never had issues with those first requests to your server.

And inversely, if you can correctly set #2, you can skip #1.

1 Like

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