golang/go · error
tls: received new session ticket from a client
Error message
tls: received new session ticket from a client
What it means
A TLS server received a NewSessionTicket message, which is a client-to-server-only artifact in TLS 1.3. Servers never process inbound NST messages; only clients do. The peer (which should be a client) sent the wrong message direction, indicating a malformed or malicious implementation. The server alerts unexpected_message.
Source
Thrown at src/crypto/tls/handshake_client_tls13.go:840
}
c.setWriteTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
c.resumptionSecret = hs.masterSecret.ResumptionMasterSecret(hs.transcript)
}
if c.quic != nil {
c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, hs.trafficSecret)
}
return nil
}
func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
if !c.isClient {
c.sendAlert(alertUnexpectedMessage)
return errors.New("tls: received new session ticket from a client")
}
if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
return nil
}
// See RFC 8446, Section 4.6.1.
if msg.lifetime == 0 {
return nil
}
lifetime := time.Duration(msg.lifetime) * time.Second
if lifetime > maxSessionTicketLifetime {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: received a session ticket with invalid lifetime")
}
if len(msg.label) == 0 {
c.sendAlert(alertDecodeError)View on GitHub (pinned to b6b368adc5)
Solutions
- Treat as a peer implementation bug; disconnect and log the peer address for investigation.
- If a TLS-terminating proxy sits in front, verify it is not injecting or forwarding handshake messages incorrectly.
- If fuzzing, this is an expected rejection — assert it and move on.
- Upgrade or replace the offending peer TLS stack.
Defensive patterns
Strategy: validation
Validate before calling
// No caller-side validation possible; the message direction is enforced by // the peer's TLS stack. Ensure you are not operating as a server expecting // inbound NSTs.
Try / catch
// In a server handler, log and close the connection on this error.
if err := conn.Read(...); err != nil {
if strings.Contains(err.Error(), "received new session ticket from a client") {
log.Warn("peer sent server-only message; likely malicious or buggy",
"remote", conn.RemoteAddr())
conn.Close()
}
} Prevention
- Run servers behind a vetted TLS terminator.
- Log unexpected_message alerts to detect scanning or fuzzing.
- Do not forward raw TLS handshake messages between directions in proxies.
When it happens
Trigger: handleNewSessionTicket is invoked on a Conn where c.isClient is false — i.e. the server-side connection received a newSessionTicketMsgTLS13 from the network peer. This requires the peer to actively transmit an NST on a server-facing connection.
Common situations: A buggy or malicious TLS client sending server-only messages, a misbehaving TLS proxy/terminator that forwards messages in the wrong direction, or a fuzz tester hitting the server with arbitrary handshake messages. Legitimate TLS clients never send NSTs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: received a session ticket with invalid lifetime
- tls: received a session ticket with empty opaque ticket labe
- tls: server sent unrequested session ticket
- tls: server selected TLS 1.3 in a renegotiation
- tls: unexpected encrypted client hello extension in server h
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/1963aec5608f0d2b.
Report an issue: GitHub.