This Jenkins error occurs when the Git plugin cannot locate the specified branch or commit in your repository. Common causes include branch name mismatches (master vs main), missing credentials, incorrect branch specifier syntax, or undefined pipeline variables. The fix typically involves updating the branch specifier to match your actual repository configuration.
The "Couldn't find any revision to build" error in Jenkins indicates that the Git plugin failed to find any valid commit or branch reference to check out. This is one of the most common Jenkins build failures related to Git configuration. When Jenkins runs a Git-based job, it: 1. Connects to the remote repository using configured credentials 2. Fetches available branches and refs based on the refspec 3. Attempts to resolve the branch specifier to a specific commit SHA 4. Checks out that commit to the workspace The error appears when step 3 fails - Jenkins cannot find any revision matching your branch specifier. The full error typically looks like: ``` ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job. Finished: FAILURE ``` You might also see related messages like: ``` > git rev-parse "refs/heads/master^{commit}" # timeout=10 > git rev-parse "master^{commit}" # timeout=10 Seen 0 remote branches ``` The "Seen 0 remote branches" message is particularly telling - it means Jenkins couldn't enumerate any branches at all, often indicating credential or URL issues rather than just branch name problems.
The most common cause is GitHub's default branch name change from master to main. Update your Jenkins job configuration:
For Freestyle Jobs:
1. Go to your job configuration
2. Navigate to Source Code Management > Git
3. Find Branches to build > Branch Specifier
4. Change */master to */main
For Pipeline Jobs:
Update your Jenkinsfile or pipeline script:
// Old configuration (fails with new repos)
git branch: 'master', url: 'https://github.com/your-org/your-repo.git'
// Updated configuration
git branch: 'main', url: 'https://github.com/your-org/your-repo.git'Or using checkout SCM:
checkout([
$class: 'GitSCM',
branches: [[name: '*/main']],
userRemoteConfigs: [[url: 'https://github.com/your-org/your-repo.git']]
])Tip: If unsure of your branch name, check your repository directly or leave the Branch Specifier blank to build any available branch.
Sometimes wildcard patterns like */main cause issues. Use the explicit refs/heads syntax:
Change the Branch Specifier to:
refs/heads/mainOr for remote tracking:
refs/remotes/origin/mainIn Pipeline scripts:
checkout([
$class: 'GitSCM',
branches: [[name: 'refs/heads/main']],
userRemoteConfigs: [[
url: 'https://github.com/your-org/your-repo.git',
credentialsId: 'github-credentials'
]]
])This explicit syntax avoids ambiguity when multiple refs could match a pattern.
If your branch specifier uses variables like ${gitlabSourceBranch} or ${sha1}, these are undefined during manual builds:
For GitLab webhooks with ${gitlabSourceBranch}:
1. Check This project is parameterized in job configuration
2. Add String Parameter:
- Name: gitlabSourceBranch
- Default Value: main (or your default branch)
For GitHub webhooks with ${sha1}:
1. Check This project is parameterized
2. Add String Parameter:
- Name: sha1
- Default Value: main
In Pipeline scripts, handle undefined variables:
def branchName = env.gitlabSourceBranch ?: 'main'
checkout([
$class: 'GitSCM',
branches: [[name: branchName]],
userRemoteConfigs: [[url: env.GIT_URL]]
])When triggered by webhook, the variable will be populated. When triggered manually, the default value is used.
Jenkins showing "Seen 0 remote branches" often indicates credential issues:
Test credentials manually:
1. Go to Manage Jenkins > Credentials
2. Find your Git credentials and note the ID
3. Use Jenkins Script Console (Manage Jenkins > Script Console):
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
Jenkins.instance,
null,
null
)
creds.each { println it.id + ": " + it.username }In your job configuration:
1. Under Source Code Management > Git > Repositories
2. Expand Advanced
3. Verify Credentials dropdown shows your credential
For Pipeline, explicitly specify credentialsId:
checkout([
$class: 'GitSCM',
branches: [[name: '*/main']],
userRemoteConfigs: [[
url: 'https://github.com/your-org/your-repo.git',
credentialsId: 'your-credential-id'
]]
])Common credential issues:
- SSH key without passphrase required for automated builds
- Personal Access Token expired or revoked
- GitHub App token doesn't have repository permission
- Username/password auth blocked (GitHub deprecated this in 2021)
Copy-pasting branch names can introduce invisible Unicode characters that break Git lookups:
Symptoms:
- Branch specifier looks correct in the UI
- Console log shows the expected branch name
- Git still can't find the revision
Fix:
1. Go to job configuration
2. In Branch Specifier field, select all text and delete it
3. Type the branch name manually - do not paste
Verify in console output:
# If you see something like this with extra characters:
> git rev-parse "βmain^{commit}" # Hidden zero-width space before 'main'
# It should look like this:
> git rev-parse "main^{commit}"Pipeline script fix:
// Ensure branch name is clean
def branch = "main".trim()
checkout([
$class: 'GitSCM',
branches: [[name: branch]],
userRemoteConfigs: [[url: env.GIT_URL]]
])If you're not sure which branch to specify, leaving it blank tells Jenkins to build any available branch:
For Freestyle jobs:
1. Go to Source Code Management > Git
2. Find Branches to build > Branch Specifier
3. Remove all text (leave completely empty)
Jenkins will now build whatever branch is available, which is useful for debugging whether the issue is branch-specific.
For webhook-triggered builds:
Leaving it blank means Jenkins will build whichever branch triggered the webhook, which is often the desired behavior.
Once you've confirmed builds work, specify the branch:
*/mainOr use a pattern to build feature branches:
*/feature-*The refspec determines which refs Jenkins fetches. Misconfigured refspec causes "cannot find revision" errors:
Default refspec:
+refs/heads/*:refs/remotes/origin/*For pull request builds (GitHub):
+refs/pull/*:refs/remotes/origin/pr/*For merge requests (GitLab):
+refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*Configure in Freestyle job:
1. Source Code Management > Git
2. Click Advanced under Repositories
3. Set Refspec field
Pipeline configuration:
checkout([
$class: 'GitSCM',
branches: [[name: 'refs/remotes/origin/pr/${ghprbPullId}/merge']],
userRemoteConfigs: [[
url: 'https://github.com/your-org/your-repo.git',
refspec: '+refs/pull/*:refs/remotes/origin/pr/*',
credentialsId: 'github-credentials'
]]
])Multiple refspecs:
refspec: '+refs/heads/*:refs/remotes/origin/* +refs/pull/*:refs/remotes/origin/pr/*'Shallow clones may not include the commit SHA you're trying to build:
Symptoms:
- Building specific commit SHAs fails
- "fatal: reference is not a tree" errors
- Works for HEAD but not for older commits
Disable shallow clone in Freestyle jobs:
1. Source Code Management > Git
2. Click Additional Behaviours > Add
3. Select Advanced clone behaviours
4. Uncheck Shallow clone or set Shallow clone depth to 0
Pipeline configuration:
checkout([
$class: 'GitSCM',
branches: [[name: '*/main']],
extensions: [
[$class: 'CloneOption',
depth: 0, // Full clone
noTags: false,
shallow: false]
],
userRemoteConfigs: [[url: 'https://github.com/your-org/your-repo.git']]
])For commit SHA builds:
// Fetch enough history to include the target commit
checkout([
$class: 'GitSCM',
branches: [[name: '${COMMIT_SHA}']],
extensions: [
[$class: 'CloneOption', depth: 100, shallow: true]
],
userRemoteConfigs: [[url: env.GIT_URL]]
])URL format issues can prevent Jenkins from connecting to the repository:
Check these common URL issues:
1. Missing .git suffix (sometimes required):
# Try with .git
https://github.com/your-org/your-repo.git
# Instead of
https://github.com/your-org/your-repo2. SSH vs HTTPS mismatch with credentials:
// For SSH credentials, use SSH URL:
[email protected]:your-org/your-repo.git
// For username/token credentials, use HTTPS:
https://github.com/your-org/your-repo.git3. Test URL accessibility from Jenkins agent:
# SSH with a pipeline step
sh 'ssh -T [email protected] || true'
# HTTPS
sh 'git ls-remote https://github.com/your-org/your-repo.git'4. For private repositories, include credentials:
checkout([
$class: 'GitSCM',
branches: [[name: '*/main']],
userRemoteConfigs: [[
url: 'https://github.com/your-org/private-repo.git',
credentialsId: 'github-pat'
]]
])### Understanding Jenkins Git Plugin Behavior
The Git plugin resolves branch specifiers through multiple attempts:
1. Exact match: refs/heads/main
2. Remote tracking: refs/remotes/origin/main
3. Pattern match: */main against all refs
4. SHA lookup: Direct commit hash resolution
When all attempts fail, you get "Couldn't find any revision to build."
### Debug with Verbose Git Output
Enable detailed Git logging to diagnose issues:
// Pipeline with verbose git
withEnv(['GIT_TRACE=1', 'GIT_CURL_VERBOSE=1']) {
checkout scm
}Or in Freestyle:
1. Manage Jenkins > Configure System
2. Find Git section
3. Set Global Config user.email (triggers git config)
### Pipeline vs Freestyle Differences
Freestyle jobs:
- Use UI-configured branch specifier
- Variables like ${sha1} work with parameterized builds
- Webhook plugins populate variables automatically
Pipeline jobs:
- checkout scm uses Jenkinsfile's SCM config
- Explicit checkout step needed for custom branches
- Environment variables must be accessed via env.
// Common pipeline patterns
pipeline {
agent any
stages {
stage('Checkout') {
steps {
// Use SCM configuration from job
checkout scm
// Or explicit configuration
checkout([
$class: 'GitSCM',
branches: [[name: env.BRANCH_NAME ?: 'main']],
userRemoteConfigs: [[
url: 'https://github.com/org/repo.git',
credentialsId: 'github-creds'
]]
])
}
}
}
}### Webhook Integration Troubleshooting
GitHub webhooks:
- Ensure webhook sends push and/or pull_request events
- Check webhook delivery status in GitHub repo settings
- Verify Jenkins URL is accessible from GitHub
GitLab webhooks:
- gitlabSourceBranch is only set on push events
- Merge request events use gitlabMergeRequestLastCommit
- Check System Hooks in GitLab admin if nothing triggers
Generic Git Server:
# Manual webhook trigger format
curl -X POST "http://jenkins-server/git/notifyCommit?url=<REPO_URL>&branches=main"### Windows-Specific Issues
Jenkins on Windows can have quoting issues with commit SHAs:
# Windows adds quotes causing failures:
git rev-parse "abc123^{commit}"
# Should be:
git rev-parse abc123^{commit}Fix: Update Git plugin to latest version (fixed in git-plugin 4.3.0+).
### Multi-Branch Pipeline Configuration
For multi-branch pipelines, branch discovery settings matter:
// Jenkinsfile in multi-branch pipeline
pipeline {
agent any
stages {
stage('Info') {
steps {
echo "Building branch: ${env.BRANCH_NAME}"
echo "Git commit: ${env.GIT_COMMIT}"
}
}
}
}Configure branch sources:
1. Branch Sources > Git
2. Set Behaviours:
- Discover branches
- Discover tags (if needed)
- Filter by name with wildcards
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git