golang/go · error
tls: invalid session encoding
Error message
tls: invalid session encoding
What it means
Returned by ParseSessionState (ticket.go:203) when the broad structural read of the session blob fails. The chained condition reads version, type byte, cipher suite, creation time, secret, extra blob, extMasterSecret flag, earlyData flag, and the certificate, asserting the secret is non-empty. If ANY of those reads fails or the secret is empty, the blob is considered corrupt or truncated and this error fires.
Source
Thrown at src/crypto/tls/ticket.go:203
// ParseSessionState parses a [SessionState] encoded by [SessionState.Bytes].
func ParseSessionState(data []byte) (*SessionState, error) {
ss := &SessionState{}
s := cryptobyte.String(data)
var typ, extMasterSecret, earlyData uint8
var cert Certificate
var extra cryptobyte.String
if !s.ReadUint16(&ss.version) ||
!s.ReadUint8(&typ) ||
!s.ReadUint16(&ss.cipherSuite) ||
!readUint64(&s, &ss.createdAt) ||
!readUint8LengthPrefixed(&s, &ss.secret) ||
!s.ReadUint24LengthPrefixed(&extra) ||
!s.ReadUint8(&extMasterSecret) ||
!s.ReadUint8(&earlyData) ||
len(ss.secret) == 0 ||
!unmarshalCertificate(&s, &cert) {
return nil, errors.New("tls: invalid session encoding")
}
for !extra.Empty() {
var e []byte
if !readUint24LengthPrefixed(&extra, &e) {
return nil, errors.New("tls: invalid session encoding")
}
ss.Extra = append(ss.Extra, e)
}
switch typ {
case 1:
ss.isClient = false
case 2:
ss.isClient = true
default:
return nil, errors.New("tls: unknown session encoding")
}
switch extMasterSecret {
case 0:View on GitHub (pinned to b6b368adc5)
Solutions
- Treat the cached blob as stale: discard it and perform a full handshake (do not retry ParseSessionState on the same bytes).
- Ensure the bytes came from SessionState.Bytes() in the same Go major version; version-stamp cached blobs if you persist them.
- Validate length and magic prefix before calling ParseSessionState if you control the encoding.
- If implementing a cache, store bytes atomically and guard against partial writes / encoding mismatches.
Example fix
// before
data := loadFromCache(key) // possibly corrupt / from old Go version
ss, err := tls.ParseSessionState(data) // -> invalid session encoding
// after
data := loadFromCache(key)
ss, err := tls.ParseSessionState(data)
if err != nil {
cache.Delete(key) // drop stale entry, fall back to full handshake
return nil
} Defensive patterns
Strategy: try-catch
Validate before calling
// Optional length sanity check before parsing cached blobs.
func looksLikeSessionState(data []byte) bool {
// SessionState header: 2-byte version + 1-byte type + 2-byte cipher + ...
return len(data) >= 16 // rough lower bound; refine per Go version
} Try / catch
ss, err := tls.ParseSessionState(data)
if err != nil {
// Treat as a stale/corrupt cache entry.
cache.Delete(key)
return nil // fall back to full handshake
} Prevention
- Version-stamp session blobs you persist so cross-version mismatches are detected early.
- Store cached bytes atomically; partial writes corrupt the encoding.
- Clear the session cache after upgrading Go major versions.
When it happens
Trigger: Calling tls.ParseSessionState on bytes that are truncated, were produced by an incompatible Go version, were corrupted in a session cache, or are not a session-state blob at all. Also when the master secret field decodes to zero length.
Common situations: Persistent ClientSessionCache that survived a Go upgrade changing the encoding; cache value mutated by an external process; deserializing a server-issued session ticket as a client SessionState (or vice versa); passing a raw NewSessionTicket message instead of a SessionState.Bytes() blob.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: unknown session encoding
- tls: server selected an invalid PSK
- tls: server selected an invalid PSK and cipher suite pair
- tls: session supported extended_master_secret but client doe
- tls: internal error: empty verified chain
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/dc34a9bbc086fc15.
Report an issue: GitHub.