Jenkins Error: 'RejectedAccessException: Scripts not permitted to use method <signature>' — Cause, Fix, and Troubleshooting Guide
Fix 'Scripts not permitted to use method <signature>' in Jenkins: use Script Approval, @NonCPS, and trusted global libraries instead of disabling the sandbox.
- #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 or Script Console snippet runs inside the Groovy sandbox, and the Script Security plugin blocks a method call it considers unsafe. The build fails with a RejectedAccessException naming the exact signature that was denied:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method java.lang.String toLowerCase
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:158)
The sandbox intercepts every method, constructor, and field access, and only allows calls that are on an approved allowlist. Anything else is rejected until an administrator approves that specific signature — or you restructure the code so it doesn’t run in the sandbox at all.
Symptoms
- A build fails with
RejectedAccessException: Scripts not permitted to use method <class> <method>. - The same code runs fine in a local Groovy shell but not in a
Jenkinsfile. - A pending entry appears under Manage Jenkins → In-process Script Approval after the failure.
- Non-admin users cannot self-approve; builds stay blocked until an admin acts.
- Calls to
new File(...),System.getenv(...), reflection, or third-party library methods are rejected. - Approving one signature just surfaces the next rejected call on the following line.
Common Root Causes
- Sandbox enabled (the default) plus a non-allowlisted call — most Java/Groovy library methods aren’t on the default allowlist and require approval.
- Direct filesystem/JVM access —
java.io.File,System,Runtime, or reflection APIs are blocked by design. - Using approvals as a habit — repeatedly approving arbitrary signatures instead of moving privileged code to a trusted library.
- Untrusted shared library — folder-scoped or non-trusted libraries also run in the sandbox, so their helper methods get rejected too.
- CPS transformation quirks — some iteration/closure patterns trigger sandbox interception on internal methods.
- Copy-pasted Script Console code into a pipeline — Script Console runs unsandboxed for admins; the same code sandboxed in a pipeline is rejected.
How to diagnose
Read the signature in the exception — it’s the exact class method argTypes you must either approve or avoid. Then decide whether this call should run in the sandbox at all (most business logic should; raw JVM access should not).
See what’s pending or already approved under Manage Jenkins → In-process Script Approval. To audit it programmatically from the Script Console (admin only):
// List currently approved signatures and any pending ones
def sa = org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval.get()
println "Approved signatures: ${sa.approvedSignatures.size()}"
sa.approvedSignatures.sort().each { println " ${it}" }
println "Pending: ${sa.pendingSignatures*.signature}"
Confirm whether your shared library is trusted (trusted libraries run outside the sandbox):
- Global Trusted Pipeline Libraries (Manage Jenkins → System) are trusted.
- Folder-scoped libraries and libraries loaded via
librarystep are not trusted.
Reproduce with the smallest snippet to find the first rejected call rather than chasing a chain of approvals.
Fixes
1. Approve the signature (narrowly, when it’s genuinely safe)
For a legitimately safe call (e.g. String.toLowerCase), an admin approves it once under Manage Jenkins → In-process Script Approval → Approve. Do this only for benign, side-effect-free signatures. Never blanket-approve constructors like java.io.File or groovy.lang.GroovyShell — that effectively hands pipeline authors arbitrary code execution on the controller.
2. Move privileged logic into a trusted global shared library
The robust fix: put the code in vars/ (or src/) of a Global Trusted Pipeline Library. Trusted-library code runs outside the sandbox, so it can call methods pipelines can’t — without opening those methods to every job:
// vars/slugify.groovy in a TRUSTED global library
def call(String input) {
// Runs outside the sandbox — no per-signature approval needed
return input.toLowerCase().replaceAll(/[^a-z0-9]+/, '-')
}
// Jenkinsfile — calls the trusted step, stays sandboxed itself
@Library('trusted-utils') _
pipeline {
agent any
stages {
stage('Name') {
steps { echo slugify(env.BRANCH_NAME) }
}
}
}
3. Use @NonCPS for pure, non-durable helpers
@NonCPS methods run as ordinary Groovy (not CPS-transformed), which can sidestep some interception and is required for iterating non-serializable objects. Keep them pure — no pipeline steps inside:
@NonCPS
def parseVersions(String json) {
new groovy.json.JsonSlurper().parseText(json).collect { it.version }
}
Note @NonCPS does not disable the sandbox — genuinely blocked calls (like new File) are still rejected. It only avoids CPS transformation.
4. Prefer built-in pipeline steps over raw Java
Replace blocked JVM calls with sandbox-safe steps:
// Instead of new File('x').text (rejected)
def body = readFile 'x'
// Instead of System.getenv('HOME') (rejected)
def home = env.HOME
// Instead of "cmd".execute() (rejected)
sh 'cmd'
5. Understand (but avoid) disabling the sandbox
You can uncheck Use Groovy Sandbox on a job, but then the entire script must be approved by an admin as a whole and runs with full controller privileges. That’s acceptable only for admin-authored, tightly reviewed jobs. Never disable the sandbox on jobs whose Jenkinsfile is editable by untrusted contributors — it’s remote code execution on your controller.
What to watch out for
- Approving signatures is a security decision, not a convenience toggle — each approval widens what every sandboxed job can do.
- Signatures like
staticMethod java.lang.System getenv,new java.io.File,method java.lang.Runtime exec, and anything reflective should almost never be approved; refactor instead. - Only global trusted libraries run unsandboxed; folder libraries do not — don’t assume moving code to any library escapes the sandbox.
@NonCPSand sandbox are orthogonal:@NonCPSchanges CPS behavior, not permissions.- Keep trusted-library code small and reviewed; it’s your controller’s privileged surface.
- Reduce approval churn by centralizing helpers in one trusted library rather than scattering ad-hoc Groovy across many
Jenkinsfiles.
Related
- Jenkins Error: ‘unable to resolve class’ — how to structure the shared library
src//vars/you move privileged code into. - Jenkins Error: ‘NotSerializableException’ — the CPS serialization error that
@NonCPShelpers often help you avoid. - Jenkins Error: ‘No such DSL method found among steps’ — when the safer built-in step you switched to isn’t installed.
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.