Why is the pre-receive hook rejecting my commit with no explanation?
Problem and Symptoms
When pushing to Bitbucket, pushes are rejected by the pre-receive hook. Developers pushing on the command line see that the pre-receive hook failed, with no other message or explanation:
╭── user@machine ~/dev/rep_1 [ main ↑ ]
╰─➤ git push
Enumerating objects: 20, done.
Counting objects: 100% (20/20), done.
Delta compression using up to 12 threads
Compressing objects: 100% (15/15), done.
Writing objects: 100% (19/19), 1.57 KiB | 1.57 MiB/s, done.
Total 19 (delta 6), reused 0 (delta 0), pack-reused 0
To https://soteri.io/bitbucket/scm/project_1/rep_1.git
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'https://soteri.io/bitbucket/scm/project_1/rep_1.git'
In your Bitbucket logs, you see errors that look like this:
[INFO] 2023-09-12 13:58:28,994 WARN [mesh-grpc-request:thread-4] admin @MMO1NVx837x62x0 127.0.0.1 "POST /scm/project_1/rep_1.git/git-receive-pack HTTP/1.1" org.slf4j.Logger com.mohami.bitbucket.security-for-bitbucket:credentials-validation-global-hook:onEnd failed: Commit '559b0279a86d633842b8350a0989d3bfb4f199a0' does not exist in repository 'rep_1'.
In your Bitbucket mesh node logs, you see errors that look like this:
2023-09-12 15:48:39,855 ERROR [git-hook:thread-1] admin 5J8FLPV7x948x6x2 @HAZTY8x948x3x0 127.0.0.1 "HostingService/HttpBackend" (>2 <5) c.a.b.m.g.AbstractHostingWriteFragmentHandler$CompletableGitHookHandler Timeout waiting for response from RPC client for git hook
java.util.concurrent.TimeoutException: null
at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1886)
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2021)
at com.atlassian.bitbucket.mesh.git.AbstractHostingWriteFragmentHandler$CompletableGitHookHandler.handle(AbstractHostingWriteFragmentHandler.java:210)
at com.atlassian.bitbucket.mesh.git.AbstractHostingWriteFragmentHandler$PreReceiveHookHandler.handle(AbstractHostingWriteFragmentHandler.java:327)
at com.atlassian.bitbucket.mesh.git.hook.DefaultGitHookService.handleRequest(DefaultGitHookService.java:315)
at com.atlassian.bitbucket.mesh.git.hook.DefaultGitHookService.lambda$handleRawRequest$1(DefaultGitHookService.java:254)
at io.grpc.Context.run(Context.java:536)
at com.atlassian.bitbucket.mesh.execution.GrpcExecutionManager$GrpcExecutionContext.run(GrpcExecutionManager.java:232)
at com.atlassian.bitbucket.mesh.git.hook.DefaultGitHookService$HookContext.applyAndRun(DefaultGitHookService.java:543)
at com.atlassian.bitbucket.mesh.git.hook.DefaultGitHookService.handleRawRequest(DefaultGitHookService.java:245)
at com.atlassian.bitbucket.mesh.git.hook.DefaultGitHookService$1.lambda$run$0(DefaultGitHookService.java:198)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Environment
Bitbucket Data Center 8.0.0+
Security for Bitbucket - all versions
The security hook is enabled either globally, at the project level, or the repository level, in either warn or block mode.
Cause
The Bitbucket Mesh system introduced in Bitbucket 8 introduced a default timeout for all git hooks that stops them after 4 minutes (hooks.callback.timeout
). This is sometimes not sufficient when scanning, especially when pushing new git branches.
Solutions
Try the push again
Security for Bitbucket caches what’s been scanned, so subsequent push attempts will skip scanning what has already been scanned.
Increase the git hooks timeout
Soteri recommends setting hooks.callback.timeout
to 1200 seconds (20 minutes).
If you’re not using dedicated Bitbucket Mesh nodes, you can set the configuration via the bitbucket.properties
in your shared home directory by adding this line:
mesh.hooks.callback.timeout = 1200
If you’re using Bitbucket Mesh nodes, set the configuration by adding this line to mesh.properties
in the home directory of the mesh nodes:
hooks.callback.timeout = 1200