golang/go · error
tls: client using inappropriate protocol fallback
Error message
tls: client using inappropriate protocol fallback
What it means
The client included TLS_FALLBACK_SCSV in its cipher suites but offered a version lower than the server's maximum supported version. Per RFC 7507, this sentinel signals intentional protocol downgrade protection; a legitimate downgrade should not occur, so the server rejects with inappropriate_fallback.
Source
Thrown at src/crypto/tls/handshake_server.go:416
func (hs *serverHandshakeState) pickCipherSuite() error {
c := hs.c
preferenceList := c.config.cipherSuites(isAESGCMPreferred(hs.clientHello.cipherSuites))
hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk)
if hs.suite == nil {
c.sendAlert(alertHandshakeFailure)
return fmt.Errorf("tls: no cipher suite supported by both client and server; client offered: %x",
hs.clientHello.cipherSuites)
}
c.cipherSuite = hs.suite.id
for _, id := range hs.clientHello.cipherSuites {
if id == TLS_FALLBACK_SCSV {
// The client is doing a fallback connection. See RFC 7507.
if hs.clientHello.vers < c.config.maxSupportedVersion(roleServer, c.quic != nil) {
c.sendAlert(alertInappropriateFallback)
return errors.New("tls: client using inappropriate protocol fallback")
}
break
}
}
return nil
}
func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
if c.flags&suiteECDHE != 0 {
if !hs.ecdheOk {
return false
}
if c.flags&suiteECSign != 0 {
if !hs.ecSignOk {
return false
}
} else if !hs.rsaSignOk {View on GitHub (pinned to b6b368adc5)
Solutions
- Stop forcing the downgrade — connect at the highest mutually supported version (TLS 1.3).
- If a downgrade retry is genuinely needed, ensure the server also lacks support for the higher version; otherwise do not send FALLBACK_SCSV.
- Remove middleware or proxies that cap MaxVersion below what the server supports.
- Update the client's retry logic to not inject FALLBACK_SCSV on the initial connection attempt.
Example fix
// before: client forces TLS 1.2 and signals fallback
cfg := &tls.Config{
MaxVersion: tls.VersionTLS12,
// somewhere FALLBACK_SCSV is appended
}
// after: let the client negotiate the highest version
cfg := &tls.Config{
MinVersion: tls.VersionTLS12,
// MaxVersion unset — defaults to highest supported Defensive patterns
Strategy: validation
Validate before calling
// Client: do not inject TLS_FALLBACK_SCSV unless performing an intentional // downgrade retry, and only after confirming the server does not support a // higher version. // Standard libraries handle this correctly — avoid manual SCSV injection.
Try / catch
// Client: catch and stop the downgrade loop.
if err != nil && strings.Contains(err.Error(), "inappropriate protocol fallback") {
// do NOT retry at an even lower version; report the failure
return err
} Prevention
- Never cap MaxVersion below what the server supports.
- Audit retry logic that lowers TLS versions on failure.
- Remove proxies/middleware that force downgrades.
When it happens
Trigger: pickCipherSuite iterates hs.clientHello.cipherSuites; finding TLS_FALLBACK_SCSV and hs.clientHello.vers < server's max supported version triggers alertInappropriateFallback.
Common situations: A client library that automatically retries with a lower TLS version after a failure and incorrectly sends FALLBACK_SCSV, a misconfigured proxy forcing downgrade, or a MITM attempting version rollback. Browser-style fallback mechanisms must only send SCSV when the downgrade is intentional AND no higher version works against this specific server.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: received new session ticket from a client
- tls: Encrypted Client Hello cannot be used pre-TLS 1.3
- tls: client does not support uncompressed connections
- tls: initial handshake had non-empty renegotiation extension
- tls: client offered only incompatible point formats
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/57135ec3ceec2549.
Report an issue: GitHub.