Jenkins CLI: "CLI handshake failed with status code 403"
The CLI connects over WebSocket by default, and since the March 2026 security fix Jenkins accepts that connection only from the address set as its Jenkins URL. With no Jenkins URL configured, or with -s naming the server another way, the handshake gets 403. Set the Jenkins URL and use exactly that address, or add -http.
The whole answer
What jenkins-cli.jar 2.580.1 printed on October 24, 2026, against a Jenkins 2.580.1 with no Jenkins URL set, signed in with an API token (exit code 15). After the first line it prints the response headers; this is the one that says why:
java -jar jenkins-cli.jar -s http://127.0.0.1:8091/ -auth @auth.txt who-am-i CLI handshake failed with status code 403 X-CLI-Error: Jenkins URL is not configured (set Jenkins URL in the configuration)
With a Jenkins URL set, connecting through any other name for the same server got the second reason. Jenkins URL http://127.0.0.1:8091/ and -s http://localhost:8091/, or the other way round:
CLI handshake failed with status code 403 X-CLI-Error: Unexpected request origin (check your reverse proxy settings)
Why it started
Jenkins' security advisory of March 18, 2026 (SECURITY-3674, a DNS rebinding issue in the WebSocket CLI's origin check) changed the check: Jenkins now compares the request's origin with the Jenkins URL configured under Manage Jenkins → System instead of with the request's own Host or X-Forwarded-Host header, and refuses the connection when no Jenkins URL is configured. The fix is in Jenkins 2.555 and LTS 2.541.3. A script that used -s http://localhost:8080/ on the server itself, or a host name the proxy rewrites, worked before and gets 403 after.
Fix it
- Set the Jenkins URL in Manage Jenkins → System → Jenkins URL, and give
-sthat exact address: the same scheme, host name and port. After we sethttp://127.0.0.1:8091/, the same command answeredAuthenticated as: tester. - Or add
-http: the CLI then uses two plain HTTP requests instead of WebSocket, and this check does not apply. With the Jenkins URL set to a different host name,-httpstill connected:java -jar jenkins-cli.jar -s http://127.0.0.1:8091/ -http -auth @auth.txt who-am-i
- The advisory names a system property,
hudson.cli.CLIAction.ACCEPT_URL_FROM_REQUEST=true, that brings back the old header-based check if the fix causes problems. It also brings back the weakness the fix closed; we did not try it.
A 401 instead is the token: -http with a wrong token ended in java.io.IOException: Server returned HTTP response code: 401 for URL: …/cli?remoting=false. And "anonymous is missing the Overall/Read permission" means no token reached Jenkins (how to send it).
Jenkins builds in IntelliJ IDEA without the CLI
Pipeline Inbox for Jenkins, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, talks to Jenkins' REST API over ordinary HTTP(S) with your user ID and API token, not through the CLI, so this WebSocket check does not stand in its way. The build list, Pipeline stages, failed tests and console logs are free; build with parameters, rebuild, stop and input steps are Pro (US$1.50 a month, with a 30-day trial).
Jenkins® is a registered trademark of LF Charities Inc.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with or endorsed by the Jenkins project or JetBrains.