Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

🐛 After SIGTERM, `cloudflared tunnel run` uses 100% of one CPU core for the whole graceful-shutdown period

オープン 初心者向け
#1,753 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る

@cyphercodes がすでに取り組んでいます。

2026年10月8日 から。

  • #1755 @cyphercodes による — オープン
  • #1760 @theolujay による — オープン

評価

難易度
1/5
見積もり時間
1時間未満
初心者へのやさしさ
88/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
go
領域
backend

調査の方向性

Issueは、supervisor/supervisor.go内でSupervisor.RunがgracefulShutdownCを対象にしているselectのbusy loopを指しています。そのループとwaitForSignalでのシグナル処理を読み、initialize()は影響を受けないことを確認してください。SIGTERM後、接続のdrain中にsupervisorがブロックし、トンネル接続が終了するか猶予期間が終了すると、引き続き終了することを検証してください。

索引モデルが issue の本文から書いたものです。

説明

Priority: Normal Type: Bug

Describe the bug
After SIGTERM, cloudflared tunnel run uses 100% of one CPU core for the whole graceful-shutdown period (up to --grace-period). It uses ~0% before the signal, including while it serves a long-lived request.

The cause is a busy loop in Supervisor.Run (supervisor/supervisor.go). On SIGTERM, waitForSignal calls close(graceShutdownC). The supervisor's main loop selects on that channel:

case <-s.gracefulShutdownC:
    shuttingDown = true

A closed channel is always ready, so this case is selected on every iteration and the for { select { ... } } loop never blocks. The loop runs until the last tunnel connection exits or the process is killed.

To Reproduce

  1. Run a local origin that serves a long-lived response (e.g. an SSE endpoint that writes one event per second for 90s).
  2. Run cloudflared tunnel --grace-period 100s --no-autoupdate --metrics 127.0.0.1:20241 run --token <token>
  3. Open the long-lived request through the tunnel hostname.
  4. kill -TERM <cloudflared pid>
  5. Sample CPU (e.g. /proc/<pid>/stat utime+stime over 3s) or watch top: cloudflared stays at 100% of one core until it exits.
  6. curl '127.0.0.1:20241/debug/pprof/goroutine?debug=2' shows the supervisor goroutine runnable inside the Run select loop, while the rest are blocked.

If it's an issue with Cloudflare Tunnel:
4. Tunnel ID: f499dceb-781e-470b-9943-3c1aa7674c30
5. cloudflared config: no config file; remotely managed tunnel run with --token, --grace-period 100s, --no-autoupdate. Protocol: QUIC (default). The loop is in the supervisor, so it should not depend on the protocol.

Expected behavior
While draining, cloudflared should sit near-idle, blocked until in-flight requests finish or the grace period ends.

Environment and versions

  • OS: Linux (Debian 13 trixie container, kernel 7.1.5)
  • Architecture: AMD64 (x86_64)
  • Version: 2026.9.3 (built 2026-09-24). The same code is on master.

Logs and errors
CPU measured over 3s windows:

idle       cpu%: 0
streaming  cpu%: 0
drain1     cpu%: 100
drain2     cpu%: 100
drain3     cpu%: 101

Log at SIGTERM:

INF Initiating graceful shutdown due to signal terminated ...
INF Unregistered tunnel connection connIndex=2 event=0 ip=198.41.192.7
INF Unregistered tunnel connection connIndex=1 event=0 ip=198.41.192.57

Goroutine dump during drain (54 goroutines; only the pprof handler is running and this one is runnable):

goroutine 61 [runnable]:
context.(*cancelCtx).Done(...)
	/usr/local/go/src/context/context.go:448
github.com/cloudflare/cloudflared/supervisor.(*Supervisor).Run(...)
	.../cloudflared/supervisor/supervisor.go:137 +0x324
github.com/cloudflare/cloudflared/supervisor.StartTunnelDaemon(...)
	.../cloudflared/supervisor/tunnel.go:104 +0x50
github.com/cloudflare/cloudflared/cmd/cloudflared/tunnel.StartServer.func5()
	.../cloudflared/cmd/cloudflared/tunnel/cmd.go:521 +0x74

Additional context
Suggested fix: set the channel to nil after the first receive. A nil channel is never ready in a select, so the loop blocks again.

case <-s.gracefulShutdownC:
    shuttingDown = true
    s.gracefulShutdownC = nil

initialize() also selects on gracefulShutdownC, but it returns immediately on receive, so it is not affected.

Impact: we run cloudflared as the ingress next to our app server and drain for up to 100s on each deploy. During that time cloudflared takes a full core away from the app server while the app server finishes in-flight requests.

主要言語
Go
スター
16k
フォーク
1.5k
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

cloudflare/cloudflared のほかの issue

cloudflare/cloudflared の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。