🐛 After SIGTERM, `cloudflared tunnel run` uses 100% of one CPU core for the whole graceful-shutdown period
@cyphercodes ci sta già lavorando.
Dal 8/10/2026.
Valutazione
- Difficoltà
- 1/5
- Tempo stimato
- Meno di un'ora
- Idoneità per principianti
- 88/100
Direzione di ricerca
L’issue indica il busy loop in supervisor/supervisor.go, all’interno del select di Supervisor.Run su gracefulShutdownC. Leggi quel loop e la gestione dei segnali in waitForSignal; initialize() non è interessato. Verifica che dopo SIGTERM il supervisor si blocchi durante il drain e che continui a terminare quando le connessioni del tunnel finiscono o scade il periodo di grazia.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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
- Run a local origin that serves a long-lived response (e.g. an SSE endpoint that writes one event per second for 90s).
- Run
cloudflared tunnel --grace-period 100s --no-autoupdate --metrics 127.0.0.1:20241 run --token <token> - Open the long-lived request through the tunnel hostname.
kill -TERM <cloudflared pid>- Sample CPU (e.g.
/proc/<pid>/statutime+stime over 3s) or watchtop: cloudflared stays at 100% of one core until it exits. curl '127.0.0.1:20241/debug/pprof/goroutine?debug=2'shows the supervisor goroutine runnable inside theRunselect 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.
- Lingua principale
- Go
- Stelle
- 16k
- Fork
- 1.5k
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di cloudflare/cloudflared
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
cloudflare/cloudflared#1761 ·
-
🐛 cfRay is missing from proxied request logs (newHTTPLogger discards the zerolog context)Forse già presa @pankajc46 l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
cloudflare/cloudflared#1756 ·
-
tunnel route ip show: --filter-network-is-subset-of sends the superset filterForse già presa @wangyusheng1985 l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 92/100
cloudflare/cloudflared#1750 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
cloudflare/cloudflared#1748 ·
-
🐛 QUIC Hijack() skips the status-written check that HTTP/2 enforcesForse già presa @Asthenia0412 l’ha presa 11 giorni fa. ApertaPriority: Normal Type: Bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
cloudflare/cloudflared#1747 ·
Tutte le issue di cloudflare/cloudflared
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
OpenTollGate/tollgate-module-basic-go#833 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
siyuan-note/siyuan#20353 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
attributes-natural-language "en-US" is rejected by PAPPL >= 1.4.12 printers (RFC 8011 requires lowercase)Forse già presa @ChrisEdgington l’ha presa oggi. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 84/100
OpenPrinting/ipp-usb#140 ·