Jenkins Error: 'WorkflowScript: 1: unable to resolve class <ClassName>' — Cause, Fix, and Troubleshooting Guide
Fix 'WorkflowScript: 1: unable to resolve class <ClassName>' in Jenkins pipelines: shared library src/ layout, @Library, imports, and missing plugin classes.
- #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 fails at compile time — before a single step runs — because Groovy cannot find a class your Jenkinsfile imports or references. The build log ends with a MultipleCompilationErrorsException whose first line reads:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 1: unable to resolve class com.example.utils.Deployer
@ line 1, column 1.
import com.example.utils.Deployer
^
1 error
The class is either not on the pipeline classpath (a shared library isn’t loaded, or its src/ layout is wrong), or the plugin that supplies the class isn’t installed. Because this is a compilation failure, none of your stages execute — the whole run is aborted immediately.
Symptoms
- The build fails instantly with
WorkflowScript: N: unable to resolve class ...and a caret pointing at animportline. - Stages never start; the console output is only the compilation stack trace.
- The pipeline worked on one controller/folder but fails on another after being copied.
- It fails only after a shared library was renamed, moved, or its version pinned to a bad branch.
- A
@Grabor third-party import that works in plain Groovy fails insideJenkinsfile. - Autocompletion in your editor is happy, but Jenkins rejects the same import.
Common Root Causes
- Shared library not loaded — you reference a library class but never declared
@Library('my-shared-lib')(or the library isn’t configured globally / at folder level). - Wrong
src/package layout — the class file isn’t atsrc/<package path>/ClassName.groovymatching itspackagedeclaration, so the library compiler can’t find it. - Missing plugin that provides the class — imports like
com.cloudbees.plugins.credentials.*orhudson.model.*resolve only if the corresponding plugin is installed on the controller. - Typo or wrong package in the import — the class name or package path doesn’t match the actual file (case-sensitive).
- Library configured but not trusted/loaded implicitly — “Load implicitly” is off and no
@Libraryannotation was added, sosrc/classes aren’t on the classpath. - Version/branch pin points at code that lacks the class —
@Library('my-shared-lib@feature-x')resolves to a branch where the class doesn’t exist yet. - Class lives in
vars/notsrc/— global variables invars/are called as steps, not imported as classes; importing them fails.
How to diagnose
First read the caret in the stack trace — it names the exact unresolved class and the line. Confirm whether it’s a library class or a plugin class.
Check that the library is actually loaded by printing the effective libraries at the top of the run. In a scripted or declarative script {} block:
// Temporary diagnostic — remove after debugging
echo "Loaded libraries: ${env.LIBRARIES ?: 'none reported'}"
try {
echo Class.forName('com.example.utils.Deployer').name
} catch (Throwable t) {
echo "Cannot load class: ${t}"
}
Verify the shared library configuration in the UI:
- Global library: Manage Jenkins → System → Global Trusted Pipeline Libraries.
- Folder library:
→ Configure → Pipeline Libraries .
Confirm the file exists at the path the package requires. A class declared package com.example.utils must live at:
(repo root)/src/com/example/utils/Deployer.groovy
For a missing-plugin case, check installed plugins from the Script Console (Manage Jenkins → Script Console):
// Is the plugin that ships this class present?
Jenkins.instance.pluginManager.plugins
.findAll { it.shortName.contains('credentials') }
.each { println "${it.shortName} ${it.version}" }
You can also list the library retrieval on the controller filesystem:
# On the controller: libraries are cached per job build
ls -R "$JENKINS_HOME/jobs/<job>/builds/<n>/libs/" 2>/dev/null
Fixes
1. Declare and load the shared library
If the class comes from a shared library, annotate the import so Jenkins retrieves it. The @Library annotation must come before the import:
@Library('my-shared-lib') _
import com.example.utils.Deployer
pipeline {
agent any
stages {
stage('Deploy') {
steps {
script {
def d = new Deployer(this)
d.run('staging')
}
}
}
}
}
The trailing _ is required — it’s the target of the annotation. Pin a version explicitly when you need reproducibility: @Library('my-shared-lib@v1.4.0') _.
2. Fix the src/ package layout
The directory structure under src/ must mirror the package declaration exactly (case-sensitive):
my-shared-lib/
├── src/
│ └── com/
│ └── example/
│ └── utils/
│ └── Deployer.groovy // package com.example.utils
└── vars/
└── deploy.groovy // called as a step: deploy()
// src/com/example/utils/Deployer.groovy
package com.example.utils
class Deployer implements Serializable {
def script
Deployer(script) { this.script = script }
void run(String env) { script.sh "deploy.sh ${env}" }
}
3. Configure the library globally or at folder scope
For a global library, add it under Manage Jenkins → System → Global Trusted Pipeline Libraries: set the name, default version (branch/tag), and a Git retrieval source. Enable Load implicitly only if every job should get it without @Library. For a single team, prefer a folder-scoped library (Folder → Configure → Pipeline Libraries) so it’s isolated and doesn’t need controller-admin rights.
4. Install the plugin that provides the class
If the unresolved class is a plugin API (e.g. com.cloudbees.plugins.credentials.CredentialsProvider), install the plugin via Manage Jenkins → Plugins → Available, then restart if prompted. Do not try to @Grab plugin jars into the pipeline — use the plugin.
5. Don’t import vars/ globals
Code in vars/deploy.groovy is a global step, not an importable class. Call it directly instead of importing:
@Library('my-shared-lib') _
pipeline {
agent any
stages {
stage('Deploy') { steps { deploy('staging') } } // no import
}
}
What to watch out for
- Put
@Library(...) _at the very top of the file; annotations after the first statement are ignored and the class stays unresolved. - Keep
src/package paths and file names case-correct — Linux controllers are case-sensitive even if your laptop isn’t. - Pin library versions in production (
@lib@tag); a floatingmaster/maincan silently drop a class when someone refactors. - Prefer trusted global libraries in
vars/over signature approvals when code needs privileged calls (see the Script Security guide below). - Restart the controller after installing a plugin that supplies imported classes; the class loader picks it up on restart.
- For recurring pipeline failures across many jobs, the free incident assistant can triage the compile trace quickly.
Related
- Jenkins Error: ‘No such DSL method found among steps’ — the step-level twin of this class-level failure, usually a missing plugin.
- Jenkins Error: ‘Scripts not permitted to use method’ — why moving code into a trusted
vars/library avoids sandbox rejections. - Jenkins Error: ‘unable to serialize / NotSerializableException’ — the runtime error you’ll meet next once your library class loads.
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.