temporalio / temporalio/temporal
Version check HTTP request has no timeout or cancellation
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 23.2k
- Forks
- 1.9k
- Avg merge
- 2d 8h
- Merged PRs (30d)
- 228
Description
Expected Behavior
The server version check should have a bounded deadline. Stopping the
VersionChecker should cancel an in-flight version-info request and allow the
background goroutine to exit.
Actual Behavior
The server version check can remain blocked indefinitely when the version-info
endpoint accepts the request but never sends a response.
common/versioninfo.Caller.Call creates an http.Client without a timeout and
uses http.NewRequest without a context. service/frontend.VersionChecker
runs the check in a background goroutine and currently uses context.TODO().
Because VersionChecker.Stop() only closes the shutdown channel, an in-flight
version check cannot be cancelled and the goroutine does not exit until the HTTP
request returns.
This does not block frontend startup, since the check runs in a goroutine, but
it can leave a background goroutine and HTTP connection stuck indefinitely.
Steps to Reproduce the Problem
- Check out the Temporal server
mainbranch and create anhttptest.Server
whose handler accepts the request and then waits indefinitely. - Configure a
versioninfo.Callerto use the test server and callCaller.Call
with a validVersionCheckRequest. - Wait for a bounded period, such as 300 ms, for
Caller.Callto return. - Observe that the call is still blocked. The same behavior leaves an
in-flight request insideVersionCheckeruncancellable byStop().
I reproduced this locally with an httptest.Server; Caller.Call was still
blocked after 300 ms.
Specifications
- Version:
mainas of 2026-09-05;go.modrequires Go 1.26.4 - Platform: Windows host with PowerShell; the behavior should be platform-independent
Possible Direction
Would it make sense to propagate a context to Caller.Call, apply a bounded
timeout to the version-info request, and cancel the checker context from
VersionChecker.Stop()?
A regression test using an httptest.Server that never responds should verify
that the request returns with a timeout or cancellation error.
No persistence, protocol, or protobuf changes should be required.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with common/versioninfo.Caller.Call and service/frontend.VersionChecker, then trace how the current context and shutdown channel are used. Use an httptest.Server that accepts a request without responding to verify the request gets a bounded timeout or cancellation and VersionChecker.Stop() lets the background goroutine exit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100