gravitational/teleport · error
session chunk already closed
Error message
session chunk already closed
What it means
errSessionChunkAlreadyClosed is an unexported error in lib/srv/app/session.go indicating an app-session chunk (the tracked, recorded unit of live app session activity) has already been closed and cannot accept new inflight work. acquire() and the release path check the inflight counter; once it is set to -1 (closed) any further acquire fails.
Source
Thrown at lib/srv/app/session.go:50
"github.com/gravitational/teleport"
apidefaults "github.com/gravitational/teleport/api/defaults"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/events/recorder"
"github.com/gravitational/teleport/lib/httplib/compress"
"github.com/gravitational/teleport/lib/httplib/reverseproxy"
rsession "github.com/gravitational/teleport/lib/session"
"github.com/gravitational/teleport/lib/srv"
"github.com/gravitational/teleport/lib/srv/app/common"
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/teleport/lib/utils"
)
// sessionChunkCloseTimeout is the default timeout used for sessionChunk.closeTimeout
const sessionChunkCloseTimeout = 1 * time.Hour
var errSessionChunkAlreadyClosed = errors.New("session chunk already closed")
// sessionChunk holds an open request handler and stream closer for an app session.
//
// An app session is only bounded by the lifetime of the certificate in
// the caller's identity, so we create sessionChunks to track and record
// chunks of live app session activity.
//
// Each chunk will emit an "app.session.chunk" event with the chunk ID
// corresponding to the session chunk's uploaded recording. These emitted
// chunk IDs can be used to aggregate all session uploads tied to the
// overarching identity SessionID.
type sessionChunk struct {
closeC chan struct{}
// id is the session chunk's uuid, which is used as the id of its session upload.
id string
// appName is the name of the app this session chunk belongs to, used as
// a Prometheus label on the active sessions gauge.
appName stringView on GitHub (pinned to 1283425b60)
Solutions
- Retry the request so a new app session/chunk is created
- Check whether the session chunk close timeout is too aggressive for your workload and adjust session recording settings
- Look for clients holding stale session IDs and force them to re-establish the session
- If it reproduces consistently, examine app service logs for close/acquire race conditions
Defensive patterns
Strategy: retry
Validate before calling
// before reusing a session id, verify the session chunk is still live
if !sessionRegistry.IsOpen(sessionID) {
sessionID = startNewAppSession(ctx, identity)
} Try / catch
resp, err := doRequestWithSession(ctx, sessionID, req)
if errors.Is(err, trace.Wrap(errSessionChunkAlreadyClosed)) || isSessionClosed(err) {
sessionID = startNewAppSession(ctx, identity)
resp, err = doRequestWithSession(ctx, sessionID, req)
} Prevention
- Treat session-closed errors by re-establishing the session, not retrying the same ID
- Keep session lifetimes shorter than the chunk close timeout or refresh them
- Avoid long-lived idle clients holding stale session IDs
When it happens
Trigger: acquire() is called on a sessionChunk after close has been initiated: s.inflight == -1, typically when a request races with session chunk timeout/close (sessionChunkCloseTimeout, default 1 hour) or with session termination.
Common situations: Long-lived app sessions whose recording chunk expired or was closed while a client keeps sending requests over the same session; load balancer replaying a request to a closing session.
Related errors
- unable to serve request due to an app configuration error. C
- unable to serve the request due to an internal error. Contac
- tokens quota exceeded. Contact your Teleport administrator
- the inference provider returned an unexpected error. Contact
- failed to fetch MySQL version
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/ab8a35eea939a165.
Report an issue: GitHub.