Errors and alerts¶
Sentinel errors¶
Test handshake errors with errors.Is.
| Error | On the server | On the client |
|---|---|---|
ErrWrongPassword |
Wrapped by the handshake error when the client's Finished message does not decrypt or does not verify. A wrong password or a simulated verifier causes it. So does a client whose records were altered on the way | Wrapped by the handshake error when the server sends bad_record_mac |
ErrUnknownUsername |
Return it from GetVerifier to send unknown_psk_identity. The handshake error is the returned error |
Wrapped by the handshake error when the server sends unknown_psk_identity |
ErrAccessDenied |
Return it or an error that wraps it from GetVerifier to send access_denied. The handshake error is the returned error |
Wrapped by the handshake error when the server sends access_denied |
The common outcomes side by side:
| Cause | Server error | Alert to the client | Client error wraps |
|---|---|---|---|
Wrong password or an unknown username with a SimulatedVerifier |
Wraps ErrWrongPassword |
bad_record_mac |
ErrWrongPassword |
GetVerifier returns ErrUnknownUsername |
The error from GetVerifier |
unknown_psk_identity |
ErrUnknownUsername |
GetVerifier returns ErrAccessDenied |
The error from GetVerifier |
access_denied |
ErrAccessDenied |
Alerts¶
An alert received from the peer is a *net.OpError in the error, with Op set to "remote error".
The error text names the alert, for example remote error: tls: bad record MAC. An alert this side
sent appears as a *net.OpError with Op set to "local error" only when the record layer or the
message parser sent it, as with bad_record_mac and decode_error. The other checks return their own
error, which describes the cause.
Alerts the server sends:
| Alert | Cause |
|---|---|
protocol_version |
The ClientHello version is below TLS 1.2 |
illegal_parameter |
A is zero modulo N, not below N or gives u = 0. Also a ClientHello without null compression |
handshake_failure |
No common cipher suite, a non-empty renegotiation_info in the ClientHello or a client Finished message that decrypts but does not verify |
unknown_psk_identity |
No srp extension or GetVerifier returned ErrUnknownUsername |
access_denied |
GetVerifier returned ErrAccessDenied |
internal_error |
GetVerifier is not set, returned another error or returned an invalid verifier |
bad_record_mac |
A record does not decrypt. In the handshake this means a wrong password |
decode_error |
A malformed handshake message, including a repeated extension or an SNI name with a trailing dot |
unexpected_message |
A handshake message out of order, including any handshake message after the handshake |
The client sends the alerts listed on Connecting as a client.
It also sends decode_error for a malformed message, unexpected_message for a message out of order
and a no_renegotiation warning for a HelloRequest after the handshake.
Other errors¶
- Configuration errors. A client
Configwithout a usable username,MinGroupBitsor cipher suite fails the handshake before anything is sent.Listenfails withoutGetVerifier. RecordHeaderError. The peer sent something that is not a TLS record, such as plain HTTP on the TLS port. ItsRecordHeaderholds the five bytes read.Connholds the underlying connection when the bytes arrived in place of the first handshake message. It is nil after a handshake or after an alert was sent.- Context errors. When the context passed to
HandshakeContextis canceled during the handshake, the connection is closed and the context's error is returned.
Every handshake error is kept. Later calls to Handshake, Read and Write on the same Conn return
it again. After a canceled HandshakeContext the kept error is the one from the closed connection,
not the context error.