Bitbucket Server PR Decoration not consistent

Must-share information:

  • Sonarqube Server version:
  • Sonarqube Scanner version:

We want to use the Sonarqube report as a way to gate our Bitbucket PRs. We have configured the Bitbucket PR decoration in accordance with this doc: Bitbucket Server Integration | SonarQube Docs

The PR decoration works for a short amount of time as you would expect. However, after a variable amount of time, the decoration starts to fail. The error message shown on Sonarqube is:
“Pull request decoration did not happen. Failed to access Bitbucket Server, the repository or the pull request”

Upon enabling DEBUG logs and looking at the ce.log file, I can see that an exception is thrown:

2021.05.20 19:41:06 WARN  ce[AXmLSskOKnPc9HCg8IoL][c.s.F.D.B.E] Pull request decoration did not happen. Failed to access Bitbucket Server, the repository or the pull request
java.lang.IllegalArgumentException: Unable to contact Bitbucket server
	at org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient.doCall(
	at org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient.doGet(
	at com.sonarsource.F.D.B.A.C.getPullRequest(Unknown Source)
	at com.sonarsource.F.D.B.E.A(Unknown Source)
	at com.sonarsource.F.D.B.E.A(Unknown Source)
	at com.sonarsource.F.D.B.B.A(Unknown Source)
	at com.sonarsource.F.D.c.A(Unknown Source)
	at java.base/java.util.Optional.ifPresent(
	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(
	at com.sonarsource.F.D.c.A(Unknown Source)
	at java.base/java.util.Optional.ifPresent(
	at com.sonarsource.F.D.c.finished(Unknown Source)
	at org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor.executeTask(
	at org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor.finished(
	at org.sonar.ce.task.step.ComputationStepExecutor.executeListener(
	at org.sonar.ce.task.step.ComputationStepExecutor.execute(
	at org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor.process(
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.executeTask(
	at org.sonar.ce.taskprocessor.CeWorkerImpl$
	at org.sonar.ce.taskprocessor.CeWorkerImpl.findAndProcessTask(
	at org.sonar.ce.taskprocessor.CeWorkerImpl$TrackRunningState.get(
	at java.base/java.util.concurrent.Executors$
	at java.base/
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(
	at java.base/java.util.concurrent.ThreadPoolExecutor$
	at java.base/
Caused by: connect timed out
	at java.base/ Method)
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at okhttp3.internal.platform.Platform.connectSocket(Platform.kt:120)
	at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:295)
	at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:207)
	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)
	at org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient.doCall(
	... 33 common frames omitted
	Suppressed: connect timed out
		... 57 common frames omitted
2021.05.20 19:41:06 INFO  ce[AXmLSskOKnPc9HCg8IoL][o.s.c.t.p.a.p.PostProjectAnalysisTasksExecutor] Pull Request decoration | status=SUCCESS | time=60044ms

When we restart the Sonarqube server, the PR decoration starts to work again. We initially setup a cronjob to restart Sonarqube every 2 days, but now that doesn’t even appear long enough. After about 24 hours after being restarted, the PR decoration starts to fail once again.

These errors would seem to indicate that there is an issue connecting to Bitbucket from Sonarqube, but as mentioned, this decoration works reliably for a short amount of time. More so, logs state that the PR decoration was actually successful.

I have verified that our connection to Bitbucket works and that the user we are using for the integration has the proper permissions. Any help identifying what might be causing this would be great.

Hey there.

Is it possible that the IP Address of your Bitbucket server (masked behind a hostname) is changing regularly?

You might be finding yourself in this situation:

It’s very likely. Our bitbucket server is behind an AWS load balancer so the underlying IPs are out of our control. Let me try putting this in place and seeing how it works. How long does Sonar set this cache by default?

It should be set by the JVM, not SonarQube. Admittedly, I am not an expert here, and I’m scratching my head over how any java-based apps integrating with other applications function if the DNS is cached indefinitely. :thinking:

I look forward to hearing if it resolves your issue.

Ah, I believe we introduced a Security Manager in v8.1 (SONAR-12617) which triggers the condition to have the DNS time to live be forever.

# default value is forever (FOREVER). For security reasons, this
# caching is made forever when a security manager is set. When a security
# manager is not set, the default behavior in this implementation
# is to cache for 30 seconds.

I’m not sure this was an intended consequence of this change, and maybe there’s something that can be done SonarQube-side. I’ll ping some more intelligent folks and see what they think :slight_smile:

Here is the bug ticket:
I was able to reproduce and test a fix. You were right about the cause of the problem, @Colin.

@vdinicola, meanwhile you can use the workaround described in the post that @Colin had already mentioned.

1 Like

I’ve had the proposed fix in place for 2 days now and the decoration looks consistent. I will keep monitoring in case this changes but so far so good. Thanks for looking into this and filing a ticket.

1 Like

Just to follow up, it’s been over a week since I put this fix in and Bitbucket pull request decorations have continued to work. Thank you all for your help.

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