Jenkins Error: 'Could not find credentials entry with ID '<credentials-id>'' — Cause, Fix, and Troubleshooting Guide
Fix 'Could not find credentials entry with ID <credentials-id>' in Jenkins: correct the ID, credential scope (folder vs global), and the binding type.
- #jenkins
- #ci-cd
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
A pipeline step tries to bind a credential that Jenkins can’t locate in a scope visible to the job, so the build fails immediately:
ERROR: Could not find credentials entry with ID 'deploy-token'
The credential ID either doesn’t exist, is spelled differently, lives in a store the job can’t see (wrong scope), or is the wrong type for the binding you used. The Credentials plugin resolves IDs by walking the job’s context — the job’s folder(s), then the global store — and if no matching entry is found in that chain, it errors out before your step runs.
Symptoms
- A step (
withCredentials,git,withAWS,sshagent) fails withCould not find credentials entry with ID '<credentials-id>'. - The credential clearly exists in the UI, but the job still can’t find it.
- A pipeline works in one folder/team and fails when copied to another.
- A newly created credential isn’t usable because of a mismatched ID.
withCredentialsfails with a type error even though the ID matches (wrong binding for the credential type).- Multibranch or shared jobs can’t see a credential stored on a specific job or a different folder.
Common Root Causes
- Wrong or misspelled ID — the
credentialsIdin theJenkinsfiledoesn’t exactly match the stored credential’s ID (case-sensitive). - Scope mismatch (folder vs global vs system) — the credential is stored in a folder the job isn’t under, or in the System scope (only usable by Jenkins itself, e.g. agent connections), not Global.
- Type mismatch — using a
usernamePasswordbinding for aSecret text, orsshUserPrivateKeyfor a username/password entry. - Credential in a different folder subtree — folder-scoped credentials are only visible to jobs inside that folder and its children.
- Deleted or regenerated credential — the entry was removed or recreated with a new ID.
- Domain restriction — the credential is scoped to a domain that doesn’t match the URL/host being used.
- JCasC/seed job drift — infrastructure-as-code created the credential with a different ID than the job expects.
How to diagnose
First confirm the exact ID. In the UI, open Manage Jenkins → Credentials (or the folder’s Credentials) and copy the ID column verbatim — not the description. IDs are case-sensitive and often differ from the human label.
List every credential the controller knows and its store/scope from the Script Console (admin):
import com.cloudbees.plugins.credentials.CredentialsProvider
import com.cloudbees.plugins.credentials.common.StandardCredentials
CredentialsProvider.lookupCredentials(StandardCredentials, Jenkins.instance, null, null)
.each { println "id=${it.id} type=${it.class.simpleName} desc=${it.description}" }
To see what a specific job/folder can resolve (this respects scope), check the folder’s Credentials page, or inspect the folder store:
// Script Console: enumerate credential stores and their contexts
com.cloudbees.plugins.credentials.CredentialsProvider.lookupStores(Jenkins.instance).each { store ->
println "Store context: ${store.contextDisplayName}"
store.getCredentials(com.cloudbees.plugins.credentials.domains.Domain.global()).each {
println " id=${it.id} (${it.class.simpleName})"
}
}
Confirm the binding matches the type — a usernamePassword credential can’t be bound with string(...).
Fixes
1. Correct the ID
Match credentialsId to the stored ID exactly:
withCredentials([string(credentialsId: 'deploy-token', variable: 'TOKEN')]) {
sh 'curl -H "Authorization: Bearer $TOKEN" https://api.example.com/deploy'
}
2. Put the credential in a scope the job can see
Move or duplicate the credential into the right store:
- Global store (Manage Jenkins → Credentials → System → Global) — visible to all jobs. Use for shared, controller-wide secrets.
- Folder store (
→ Credentials ) — visible only to jobs in that folder subtree. Use to isolate a team’s secrets. If your job is underTeam-A/, the credential must live inTeam-A(or an ancestor / global), not inTeam-B. - System scope is for Jenkins internals (agent launchers) and is not available to builds — don’t store pipeline secrets there.
3. Use the binding that matches the credential type
Each credential type has a specific withCredentials binding:
// Secret text
withCredentials([string(credentialsId: 'api-key', variable: 'API_KEY')]) {
sh 'deploy --key "$API_KEY"'
}
// Username + password
withCredentials([usernamePassword(credentialsId: 'registry-creds',
usernameVariable: 'REG_USER', passwordVariable: 'REG_PASS')]) {
sh 'echo "$REG_PASS" | docker login registry.example.com -u "$REG_USER" --password-stdin'
}
// SSH private key
withCredentials([sshUserPrivateKey(credentialsId: 'deploy-key',
keyFileVariable: 'KEYFILE', usernameVariable: 'SSH_USER')]) {
sh 'ssh -i "$KEYFILE" "$SSH_USER"@app-01 "systemctl restart app"'
}
For SSH agents, sshagent takes the same SSH-key credential by ID:
sshagent(credentials: ['deploy-key']) {
sh 'ssh deploy@app-01 "./release.sh"'
}
4. Reference folder-scoped credentials from the right job location
If the job legitimately needs a shared secret, promote the credential to a common ancestor folder or to Global rather than copying it into every folder. Keep team-specific secrets folder-scoped so blast radius stays small.
5. Align infrastructure-as-code IDs
If credentials are provisioned via JCasC or a seed job, make the id field authoritative and reference that same string in every Jenkinsfile:
# jenkins.yaml (JCasC)
credentials:
system:
domainCredentials:
- credentials:
- string:
scope: GLOBAL
id: "deploy-token" # must match credentialsId in pipelines
secret: "${DEPLOY_TOKEN}" # injected from env/secret store
description: "Deploy API token"
What to watch out for
- Reference the credential ID, never the description — they’re different fields and only the ID is matched.
- IDs are case-sensitive;
Deploy-Tokenanddeploy-tokenare different entries. - Keep secrets in Global or Folder scope; System scope is invisible to builds.
- Folder-scoped credentials don’t leak upward — a parent job can’t see a child folder’s store.
- Match the binding to the type; a type mismatch throws even when the ID is correct.
- Never
echoa bound secret — Jenkins masks known secret strings in logs, but constructed variants can leak. Prefer--password-stdinand files over inline args. - For recurring credential-resolution failures across many pipelines, the Jenkins troubleshooting hub collects the related guides.
Related
- Jenkins Error: ‘No such DSL method found among steps’ — when
withCredentials/withAWS/sshagentitself is missing because the plugin isn’t installed. - Jenkins Error: ‘script returned exit code 1’ — the exit-code failure you often hit next when an authenticated command fails.
- GitLab CI Error: ‘permission denied (publickey)’ — the analogous SSH-key credential failure on GitLab, for cross-CI teams.
More Jenkins prompts & error guides
Every Jenkins AI prompt and troubleshooting guide, in one place.
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.