← Week 3: mTLS and TLS Extensions

Day 17: Alert Protocol and Error Handling

Phase 1 · May 30, 2026

← Week 3: mTLS and TLS Extensions

Agenda (2–3 hours)

  • Read (45 min): RFC 8446 §6 (Alert Protocol), Appendix B.2 (Alert messages list)
  • Study (45 min): Alert taxonomy, connection teardown, common failure modes
  • Practice (60 min): Trigger 3 specific alert types deliberately
  • Challenge (30 min): Diagnose and document each failure
← Week 3: mTLS and TLS Extensions

Alert Protocol Structure

struct {
    AlertLevel level;        // warning(1) or fatal(2)
    AlertDescription desc;   // specific error code
} Alert;

In TLS 1.3, all alerts that cause connection termination are fatal in practice.
The level field is kept for backward compatibility only — ignore it for semantic meaning.

After a fatal alert, the connection must be torn down. No data may be sent after a fatal alert.

← Week 3: mTLS and TLS Extensions

Common Alert Descriptions

Value Name Cause
0 close_notify Clean shutdown
10 unexpected_message Out-of-order message
20 bad_record_mac AEAD authentication failure
40 handshake_failure No acceptable cipher/extension
42 bad_certificate Cert is malformed
44 certificate_revoked Cert is in CRL/OCSP revoked
45 certificate_expired Past NotAfter
46 certificate_unknown Cert is in the chain but untrusted
48 unknown_ca Root CA not trusted
50 decode_error Failed to parse a message
70 protocol_version Version not supported
112 unrecognized_name SNI hostname not handled
116 certificate_required mTLS: client cert missing
← Week 3: mTLS and TLS Extensions

Connection Teardown

Clean close:

→ Alert(close_notify)   // "I'm done sending"
← Alert(close_notify)   // "acknowledged"

Both sides send close_notify before closing the TCP connection.
This prevents truncation attacks (attacker closes TCP to cut off data).

Abrupt close (error):

→ Alert(fatal, <error>)
  [TCP close, no response expected]
← Week 3: mTLS and TLS Extensions

Practice Exercise

Deliberately trigger each of these alerts and capture the exact error:

# 1. certificate_expired: connect to a server with an expired cert
openssl s_client -connect expired.badssl.com:443 2>&1 | grep -E "alert|verify"

# 2. unknown_ca: present cert from untrusted CA
openssl s_client -connect self-signed.badssl.com:443 2>&1 | grep -E "alert|verify"

# 3. wrong_cert: present wrong cert for SNI
openssl s_client -connect wrong.host.badssl.com:443 2>&1 | grep -E "alert|verify"

# 4. Force handshake_failure: no overlapping cipher suites
openssl s_client -connect google.com:443 -cipher NULL 2>&1 | grep -E "alert|error"

badssl.com provides intentionally broken TLS configurations for testing.

← Week 3: mTLS and TLS Extensions

Challenge Assignment

Create a TLS alert reference card in Markdown covering these 8 scenarios:

Scenario Alert Alert Code Openssl command to reproduce Root cause
Expired cert
Self-signed / unknown CA
SNI mismatch
Client cert required but not sent
AEAD tag verification failure
No overlapping cipher suites
TLS version mismatch
Clean close

Fill in every column from RFC 8446 Appendix B.2 and your lab results.

← Week 3: mTLS and TLS Extensions

Resources

  • RFC 8446 §6: Alert Protocol
  • RFC 8446 Appendix B.2: Alert messages
  • badssl.com: intentionally broken TLS endpoints for testing