apache/beam · warning
Control channel closed.
Error message
Control channel closed.
What it means
The Beam TypeScript worker warns 'Control channel closed.' when the gRPC control stream from the Fn API control service ends. The constructor then closes all data channels best-effort. This indicates the runner/controller closed or terminated the control connection, so the worker can no longer receive instructions.
Solutions
- If the pipeline completed normally, ignore — this is expected shutdown logging.
- If it appears mid-run, check connectivity/proxy keepalive settings between worker and control service and inspect runner logs for harness restarts.
- Rely on the runner's retry/restart of workers; ensure the control service address and credentials are correct.
Example fix
// before
worker without reconnect handling; channel end -> closed permanently
// after
controlChannel.on("end", () => {
if (!shuttingDown) {
console.error("Control channel closed unexpectedly; restarting worker");
restart();
}
}); Defensive patterns
Strategy: try-catch
Try / catch
controlChannel.on("end", () => {
if (!shuttingDown) {
console.error("Control channel closed unexpectedly");
scheduleWorkerRestart();
}
});
controlChannel.on("error", (err) => console.error("Control channel error:", err)); Prevention
- Configure gRPC keepalive so long-lived control streams survive idle proxies
- Verify control service address, TLS, and credentials before launching workers
- Check runner/harness logs when this appears mid-job rather than at shutdown
When it happens
Trigger: The control gRPC server stream emits 'end' — e.g. the job finishes, the runner shuts down the harness, or the control connection drops unexpectedly.
Common situations: Normal pipeline shutdown (benign); network interruption or proxy killing long-lived gRPC streams; the controlling process crashing so the worker's channels end prematurely.
Related errors
- Append to stream failed with Status Code . The stream may…
- control.Recv failed
- Data should not come in via process.
- failed to create data client on
- Not expecting timers.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d642d48fce80e3d6.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/typescript/src/apache_beam/worker/worker.ts:96
metricsShortIdCache = new MetricsShortIdCache();
constructor(
private id: string,
private endpoints: WorkerEndpoints,
options: Object = {},
) {
const metadata = new grpc.Metadata();
metadata.add("worker_id", this.id);
this.controlClient = new BeamFnControlClient(
endpoints.controlUrl,
grpc.ChannelCredentials.createInsecure(),
{},
{},
);
this.controlChannel = this.controlClient.control(metadata);
this.controlChannel.on("data", this.handleRequest.bind(this));
this.controlChannel.on("end", () => {
console.warn("Control channel closed.");
for (const dataChannel of this.dataChannels.values()) {
try {
// Best effort.
dataChannel.close();
} finally {
}
}
for (const stateChannel of this.stateChannels.values()) {
try {
// Best effort.
stateChannel.close();
} finally {
}
}
});
}
async wait() {View on GitHub (pinned to 12126d8942)