SonarQube MR decorator tries to connect to HTTPS port 80 on second notes fetch

Versions used:

  • SonarQube 8.9.1.44547 Developer Edition
  • sonar-scanner-cli:latest Docker container running in GitLab CI
  • GitLab 14.0.2 Community Edition (self-hosted)

Setup:

We’re using SonarQube to analyze our code in GitLab merge requests.
Everything seems to be working fine, including login to SonarQube via GitLab. However, there is one issue with merge request decoration.
The GitLab API URL is set to https://git.provider.com/api/v4 in the ALM integration settings (URL changed for privacy reasons), SonarQube successfully validated the configuration.
The GitLab URL in the ALM integration settings is set to https://git.provider.com

Error observed:

When the merge request includes a lot of notes and there are multiple pages to load, the merge request decoration fails as you can see from the SonarQube Compute Engine logs:

2021.07.02 13:53:36 INFO  ce[AXpnfwCIV-8YgX-7qfdM][c.s.F.D.E.B] GitLab's instance URL from the scanner ('http://git.provider.com/api/v4') is overridden by the settings ('https://git.provider.com/api/v4')
2021.07.02 13:53:36 INFO  ce[AXpnfwCIV-8YgX-7qfdM][c.s.F.D.E.B] GitLab's project ID from the scanner ('21') is overridden by the settings ('21')
2021.07.02 13:53:36 TRACE ce[AXpnfwCIV-8YgX-7qfdM][sql] time=0ms | sql=select pb.uuid as uuid, pb.project_uuid as projectUuid, pb.kee as kee, pb.branch_type as branchType, pb.merge_branch_uuid as mergeBranchUuid, pb.pull_request_binary as pullRequestBinary, pb.exclude_from_purge as excludeFromPurge, pb.need_issue_sync as needIssueSync from project_branches pb where pb.project_uuid = ? and pb.kee = ? and pb.branch_type = ? | params=AXkNazzUIEM8XDb7WpJn, 64, PULL_REQUEST
2021.07.02 13:53:36 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][c.s.F.D.E.D] loading notes from [https://git.provider.com/api/v4/projects/21/merge_requests/64/notes]
2021.07.02 13:53:36 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][c.s.F.D.E.D] get notes : [https://git.provider.com/api/v4/projects/21/merge_requests/64/notes]
2021.07.02 13:53:36 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][o.i.http2.Http2] >> CONNECTION 505249202a20485454502f322e300d0a0d0a534d0d0a0d0a
2021.07.02 13:53:36 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][o.i.http2.Http2] >> 0x00000000     6 SETTINGS      
2021.07.02 13:53:36 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][o.i.http2.Http2] >> 0x00000000     4 WINDOW_UPDATE 
2021.07.02 13:53:36 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][o.i.c.TaskRunner] Q10073 scheduled after   0 µs: OkHttp git.provider.com
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10073 starting              : OkHttp git.provider.com
2021.07.02 13:53:36 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][o.i.c.TaskRunner] Q10005 scheduled after   0 µs: OkHttp ConnectionPool
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10005 starting              : OkHttp ConnectionPool
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10005 run again after 300 s : OkHttp ConnectionPool
2021.07.02 13:53:36 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][o.i.http2.Http2] >> 0x00000003    94 HEADERS       END_STREAM|END_HEADERS
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10005 finished run in 345 µs: OkHttp ConnectionPool
2021.07.02 13:53:36 DEBUG ce[][o.i.http2.Http2] << 0x00000000    18 SETTINGS      
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10070 scheduled after   0 µs: OkHttp git.provider.com applyAndAckSettings
2021.07.02 13:53:36 DEBUG ce[][o.i.http2.Http2] << 0x00000000     4 WINDOW_UPDATE 
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10070 starting              : OkHttp git.provider.com applyAndAckSettings
2021.07.02 13:53:36 DEBUG ce[][o.i.http2.Http2] << 0x00000000     0 SETTINGS      ACK
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10072 scheduled after   0 µs: OkHttp git.provider.com onSettings
2021.07.02 13:53:36 DEBUG ce[][o.i.http2.Http2] >> 0x00000000     0 SETTINGS      ACK
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10072 starting              : OkHttp git.provider.com onSettings
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10072 finished run in   9 ms: OkHttp git.provider.com onSettings
2021.07.02 13:53:36 DEBUG ce[][o.i.c.TaskRunner] Q10070 finished run in   9 ms: OkHttp git.provider.com applyAndAckSettings
2021.07.02 13:53:37 DEBUG ce[][o.i.http2.Http2] << 0x00000003   898 HEADERS       END_HEADERS
2021.07.02 13:53:37 DEBUG ce[][o.i.http2.Http2] << 0x00000003  3210 DATA          
2021.07.02 13:53:37 DEBUG ce[][o.i.http2.Http2] << 0x00000003     0 DATA          END_STREAM
2021.07.02 13:53:37 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][o.i.c.TaskRunner] Q10005 scheduled after   0 µs: OkHttp ConnectionPool
2021.07.02 13:53:37 DEBUG ce[][o.i.c.TaskRunner] Q10005 starting              : OkHttp ConnectionPool
2021.07.02 13:53:37 DEBUG ce[][o.i.c.TaskRunner] Q10005 run again after 300 s : OkHttp ConnectionPool
2021.07.02 13:53:37 DEBUG ce[][o.i.c.TaskRunner] Q10005 finished run in 229 µs: OkHttp ConnectionPool
2021.07.02 13:53:37 TRACE ce[AXpnfwCIV-8YgX-7qfdM][c.s.F.D.E.D] loading notes payload result : [*payload hidden for privacy reasons*]
2021.07.02 13:53:37 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][c.s.F.D.E.D] loading notes from [https://git.provider.com:80/api/v4/projects/21/merge_requests/64/notes?activity_filter=all_notes&id=21&noteable_id=64&order_by=created_at&page=2&per_page=20&sort=desc]
2021.07.02 13:53:37 DEBUG ce[AXpnfwCIV-8YgX-7qfdM][c.s.F.D.E.D] get notes : [https://git.provider.com:80/api/v4/projects/21/merge_requests/64/notes?activity_filter=all_notes&id=21&noteable_id=64&order_by=created_at&page=2&per_page=20&sort=desc]
2021.07.02 13:53:37 ERROR ce[AXpnfwCIV-8YgX-7qfdM][c.s.F.D.E.A] An exception was thrown during Merge Request decoration : Unsupported or unrecognized SSL message
2021.07.02 13:53:37 TRACE ce[AXpnfwCIV-8YgX-7qfdM][sql] time=0ms | sql=insert into ce_task_message ( uuid, task_uuid, message, message_type, created_at ) values ( ?, ?, ?, ?, ? ) | params=AXpnfwvmj9Khos8f3kzO, AXpnfwCIV-8YgX-7qfdM, Merge Request decoration failed. Please check your configuration and the connectivity to GitLab, GENERIC, 1625234017254
2021.07.02 13:53:37 ERROR ce[AXpnfwCIV-8YgX-7qfdM][o.s.c.t.p.a.p.PostProjectAnalysisTasksExecutor] Execution of task class com.sonarsource.F.D.c failed
java.lang.IllegalStateException: Unsupported or unrecognized SSL message
	at com.sonarsource.F.D.E.D.getAllNotes(Unknown Source)
	at com.sonarsource.F.D.E.D.deleteAllUserNotes(Unknown Source)
	at com.sonarsource.F.D.E.A.A(Unknown Source)
	at com.sonarsource.F.D.c.A(Unknown Source)
	at java.base/java.util.Optional.ifPresent(Unknown Source)
	at com.sonarsource.F.D.c.B(Unknown Source)
	at com.sonarsource.F.D.c.A(Unknown Source)
	at org.sonar.ce.async.SynchronousAsyncExecution.addToQueue(SynchronousAsyncExecution.java:27)
	at com.sonarsource.F.D.c.A(Unknown Source)
	at java.base/java.util.Optional.ifPresent(Unknown Source)
	at com.sonarsource.F.D.c.finished(Unknown Source)
	at org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor.executeTask(PostProjectAnalysisTasksExecutor.java:118)
	at org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor.finished(PostProjectAnalysisTasksExecutor.java:109)
	at org.sonar.ce.task.step.ComputationStepExecutor.executeListener(ComputationStepExecutor.java:91)
	at org.sonar.ce.task.step.ComputationStepExecutor.execute(ComputationStepExecutor.java:63)
	at org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor.process(ReportTaskProcessor.java:81)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.executeTask(CeWorkerImpl.java:212)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.run(CeWorkerImpl.java:194)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.findAndProcessTask(CeWorkerImpl.java:160)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$TrackRunningState.get(CeWorkerImpl.java:135)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:87)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:53)
	at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:125)
	at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:69)
	at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:78)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
	at java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(Unknown Source)
	at java.base/sun.security.ssl.SSLSocketInputRecord.decode(Unknown Source)
	at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379)
	at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)
	at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)
	at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
	at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
	at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
	at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
	at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
	at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
	at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
	... 31 common frames omitted
2021.07.02 13:53:37 INFO  ce[AXpnfwCIV-8YgX-7qfdM][o.s.c.t.p.a.p.PostProjectAnalysisTasksExecutor] Pull Request decoration | status=FAILED | time=336ms

As you can see, there are two requests to the GitLab API, one to https://git.provider.com/api/v4/projects/21/merge_requests/64/notes and the second one to https://git.provider.com:80/api/v4/projects/21/merge_requests/64/notes?activity_filter=all_notes&id=21&noteable_id=64&order_by=created_at&page=2&per_page=20&sort=desc.
The first request is performed successfully and the fetched data is valid. For some reason however, SonarQube appends port 80 to the second request URL which of course breaks the SSL connection.

As said, the setup works including decoration when there are only a few notes in a merge request so something breaks when a second API call must be made.
I haven’t found a workaround for this issue yet. Any help is appreciated.

We found a possible issue in our GitLab instance, for some reason the GitLab URLs in the CI variables always start with http:// instead of https://. Maybe this is confusing SonarQube, even though I set the URLs to https:// in the SonarQube configuration as described above.

Still, as this issue only occurs in the second notes fetch, this seems to be partly a SonarQube issue. It should correctly use the URL override in the second (and all following) API calls as well.

1 Like

Hi, the SonarQube “follow pagination” mechanism relies on what Gitlab return in headers. So if you call manually your Gitlab API

https://git.provider.com/api/v4/projects/21/merge_requests/64/notes

You should see in Gitlab response header link a few links for pagination. That’s where this 80 is from. To me, it looks like your Gitlab external URL is misconfigured.

1 Like

Hi Pierre, thanks for the reply. We’re currently investigating why our GitLab instance is not providing HTTPS URLs even though we set the external URL to HTTPS.

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