{"record":{"id":"dc34a9bbc086fc15","repo":"golang/go","slug":"tls-invalid-session-encoding","errorCode":null,"errorMessage":"tls: invalid session encoding","messagePattern":"tls: invalid session encoding","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/ticket.go","lineNumber":203,"sourceCode":"\n// ParseSessionState parses a [SessionState] encoded by [SessionState.Bytes].\nfunc ParseSessionState(data []byte) (*SessionState, error) {\n\tss := &SessionState{}\n\ts := cryptobyte.String(data)\n\tvar typ, extMasterSecret, earlyData uint8\n\tvar cert Certificate\n\tvar extra cryptobyte.String\n\tif !s.ReadUint16(&ss.version) ||\n\t\t!s.ReadUint8(&typ) ||\n\t\t!s.ReadUint16(&ss.cipherSuite) ||\n\t\t!readUint64(&s, &ss.createdAt) ||\n\t\t!readUint8LengthPrefixed(&s, &ss.secret) ||\n\t\t!s.ReadUint24LengthPrefixed(&extra) ||\n\t\t!s.ReadUint8(&extMasterSecret) ||\n\t\t!s.ReadUint8(&earlyData) ||\n\t\tlen(ss.secret) == 0 ||\n\t\t!unmarshalCertificate(&s, &cert) {\n\t\treturn nil, errors.New(\"tls: invalid session encoding\")\n\t}\n\tfor !extra.Empty() {\n\t\tvar e []byte\n\t\tif !readUint24LengthPrefixed(&extra, &e) {\n\t\t\treturn nil, errors.New(\"tls: invalid session encoding\")\n\t\t}\n\t\tss.Extra = append(ss.Extra, e)\n\t}\n\tswitch typ {\n\tcase 1:\n\t\tss.isClient = false\n\tcase 2:\n\t\tss.isClient = true\n\tdefault:\n\t\treturn nil, errors.New(\"tls: unknown session encoding\")\n\t}\n\tswitch extMasterSecret {\n\tcase 0:","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/ticket.go#L185-L221","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ndata := loadFromCache(key) // possibly corrupt / from old Go version\nss, err := tls.ParseSessionState(data) // -> invalid session encoding\n\n// after\ndata := loadFromCache(key)\nss, err := tls.ParseSessionState(data)\nif err != nil {\n    cache.Delete(key) // drop stale entry, fall back to full handshake\n    return nil\n}","handlingStrategy":"try-catch","validationCode":"// Optional length sanity check before parsing cached blobs.\nfunc looksLikeSessionState(data []byte) bool {\n    // SessionState header: 2-byte version + 1-byte type + 2-byte cipher + ...\n    return len(data) >= 16 // rough lower bound; refine per Go version\n}","typeGuard":null,"tryCatchPattern":"ss, err := tls.ParseSessionState(data)\nif err != nil {\n    // Treat as a stale/corrupt cache entry.\n    cache.Delete(key)\n    return nil // fall back to full handshake\n}","preventionTips":["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."],"tags":["tls","session-resumption","deserialization","corruption"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}