Jenkins Error: 'hudson.remoting.ChannelClosedException: Channel "unknown": Remote call ... failed. The channel is closing down or has closed down' — Cause, Fix, and Troubleshooting Guide
Fix Jenkins 'hudson.remoting.ChannelClosedException: the channel is closing down or has closed down': diagnose agent disconnects, OOM kills, and network drops.
- #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
The remoting channel between the Jenkins controller and an agent has closed while a build was still trying to use it. Every command the controller sends to an agent — running a shell step, copying a file, reading a workspace — travels over this channel, so when it drops the build fails immediately with:
hudson.remoting.ChannelClosedException: Channel "unknown": Remote call to agent-01 failed. The channel is closing down or has closed down.
at hudson.remoting.Channel.send(Channel.java:...)
at hudson.remoting.Request.call(Request.java:...)
at hudson.remoting.Channel.call(Channel.java:...)
This is almost never a bug in your pipeline logic — the connection to the agent went away. The real cause sits underneath: the agent JVM was killed, the network blipped, a firewall reset an idle connection, or the ping thread declared the agent dead. Diagnosis is about finding why the far end vanished.
Symptoms
- A build fails mid-step with
ChannelClosedException/ “the channel is closing down or has closed down”. - The agent shows as offline (or briefly flaps offline then back) in Manage Jenkins → Nodes right after the failure.
- The controller log records
Ping failed. Terminating the channelorConnection was aborted. - Failures cluster on one flaky agent, one network segment, or on long/idle steps.
- Inbound (JNLP) agents log
Terminatedor reconnect loops in their own console output. - The agent host shows an OOM kill, a service restart, or a node reboot around the failure time.
Common Root Causes
- Agent JVM killed (OOM or crash) — the remoting process on the agent died (out of memory, kernel OOM-killer, host running the container was reclaimed), so the channel closed abruptly.
- Network blip / connection reset — a transient loss between controller and agent, or a stateful firewall/load balancer that drops idle TCP connections, tears the channel down.
- Ping thread timeout — the controller’s ping thread got no response within the timeout (agent under heavy GC or CPU starvation) and proactively terminated the channel.
- Inbound (JNLP) agent disconnect — the reverse-proxy in front of the JNLP port dropped or timed out the WebSocket/TCP connection, or two agents shared one secret and fought over the slot.
- Java version mismatch — controller and agent run incompatible Java versions, causing remoting handshake or serialization failures that close the channel.
- Firewall / idle timeout — a stateful firewall between the two hosts silently expires the connection during a long, quiet step.
How to diagnose
Look at both ends. The controller side is in the service log; the agent side is on the node’s log page or the agent host itself.
Controller log — find whether it was a ping timeout or a hard close:
journalctl -u jenkins --since '30 min ago' \
| grep -iE 'ChannelClosed|Ping failed|Terminating the channel|is offline|reconnect'
Check the agent’s own log page in the UI (Manage Jenkins → Nodes → agent-01 → Log) and, on the agent host, whether the JVM was OOM-killed or the service restarted:
# On the agent host
dmesg -T | grep -i 'killed process\|out of memory'
systemctl status jenkins-agent 2>/dev/null || journalctl --since '30 min ago' | grep -i agent
Confirm both sides run compatible Java, since a mismatch causes handshake-time channel closes:
# Controller
java -version
# Agent
ssh agent-01 'java -version'
From the Script Console, inspect the live channel state and configured ping settings:
// Which agents are online, and is the channel alive? (Script Console)
Jenkins.instance.computers.each { c ->
println "${c.name}\tonline=${c.online}\tchannel=${c.channel != null}"
}
Fixes
1. Fix an OOM/killed agent JVM
If the agent died from memory pressure, raise the agent remoting heap and enable a dump so you can confirm it. For an inbound agent:
java -Xmx2g -XX:+UseG1GC \
-XX:+HeapDumpOnOutOfMemoryError \
-jar agent.jar -jnlpUrl https://jenkins.example.com/computer/agent-01/jenkins-agent.jnlp
Right-size the host and container memory so the kernel OOM-killer does not reap the JVM. See the heap-exhaustion guide linked below for sizing detail.
2. Tune the ping/keep-alive so blips do not kill healthy channels
If channels drop during long, quiet steps, the ping thread or a firewall idle timeout is the culprit. Increase tolerance under Manage Jenkins → System → (Advanced) TCP port / ping or via the remoting system properties on the controller:
# Controller JVM options — be more tolerant of transient stalls
JENKINS_JAVA_OPTIONS="-Dhudson.remoting.Launcher.pingIntervalSec=300 \
-Dhudson.slaves.ChannelPinger.pingIntervalMinutes=10 \
-Dhudson.slaves.ChannelPinger.pingTimeoutSeconds=240"
Do not disable pinging entirely — you want dead agents detected, just not healthy ones killed.
3. Keep the connection alive through firewalls / proxies
For inbound agents behind a reverse proxy, prefer the WebSocket transport, which survives proxies far better than raw TCP:
java -jar agent.jar -webSocket \
-url https://jenkins.example.com/ -secret <agent-secret> -name agent-01
On the proxy, raise the idle/read timeout for the agent endpoint so long steps are not cut off, and enable TCP keep-alives on the agent host (net.ipv4.tcp_keepalive_time) so idle connections are refreshed before a stateful firewall expires them.
4. Make the build resilient and retry connection-level failures
A transient channel drop should not necessarily fail the whole pipeline. Wrap connection-sensitive work so it retries on a fresh executor:
pipeline {
agent none
stages {
stage('Test') {
steps {
retry(count: 2) {
node('linux') {
timeout(time: 30, unit: 'MINUTES') {
sh './run-tests.sh'
}
}
}
}
}
}
}
5. Align Java versions
Run the same major Java version (or a documented-compatible pair) on controller and all agents. Pin the agent image/base so an unattended upgrade cannot drift the JVM out of remoting compatibility.
What to watch out for
Channel "unknown"in the message is normal — remoting had not finished naming the channel, or it is already torn down. Do not read meaning into “unknown”; read the agent name in “Remote call to agent-01”.- Correlate timestamps across three logs (controller, agent, agent host kernel) before concluding — a channel close is a symptom whose cause lives on the far end.
- Do not paper over a real OOM by cranking ping timeouts; you will just wait longer to see the same crash.
- Watch for one flaky agent poisoning many builds. Take it offline and drain it rather than letting it keep failing jobs.
- Sharing a JNLP secret across two agent processes causes constant channel flapping — one name, one running agent.
- For live incidents, the free incident assistant can correlate the controller and agent logs for you.
Related
- Jenkins Error: agent went offline during build — the node-level view of the same disconnect, with reconnection tuning.
- Jenkins Error: java.lang.OutOfMemoryError: Java heap space — an OOM-killed agent JVM is a leading cause of channel closes.
- Jenkins Error: java.net.SocketTimeoutException — the timeout variant of controller/agent connectivity failures.
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.