{"record":{"id":"0c47078cd7e74586","repo":"golang/go","slug":"tls-server-s-finished-message-was-incorrect","errorCode":null,"errorMessage":"tls: server's Finished message was incorrect","messagePattern":"tls: server's Finished message was incorrect","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/crypto/tls/handshake_client.go","lineNumber":1013,"sourceCode":"\n\t// finishedMsg is included in the transcript, but not until after we\n\t// check the client version, since the state before this message was\n\t// sent is used during verification.\n\tmsg, err := c.readHandshake(nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tserverFinished, ok := msg.(*finishedMsg)\n\tif !ok {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(serverFinished, msg)\n\t}\n\n\tverify := hs.finishedHash.serverSum(hs.masterSecret)\n\tif len(verify) != len(serverFinished.verifyData) ||\n\t\tsubtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {\n\t\tc.sendAlert(alertHandshakeFailure)\n\t\treturn errors.New(\"tls: server's Finished message was incorrect\")\n\t}\n\n\tif err := transcriptMsg(serverFinished, &hs.finishedHash); err != nil {\n\t\treturn err\n\t}\n\n\tcopy(out, verify)\n\treturn nil\n}\n\nfunc (hs *clientHandshakeState) readSessionTicket() error {\n\tif !hs.serverHello.ticketSupported {\n\t\treturn nil\n\t}\n\tc := hs.c\n\n\tif !hs.hello.ticketSupported {\n\t\tc.sendAlert(alertIllegalParameter)","sourceCodeStart":995,"sourceCodeEnd":1031,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client.go#L995-L1031","documentation":"The Finished message is the integrity capstone of the handshake: verify_data is an HMAC over the entire transcript keyed by the master secret. The client computes verify := hs.finishedHash.serverSum(hs.masterSecret) and compares in constant time against serverFinished.verifyData. A length mismatch or ConstantTimeCompare != 1 means the master secret differs or the transcript was tampered with — the handshake is aborted with alertHandshakeFailure.","triggerScenarios":"A MitM that cannot compute the correct master secret; corrupted handshake packets; incompatible cipher/version computation between endpoints; a middlebox re-encrypting with the wrong keys; buggy crypto path (FIPS / GODEBUG forcing divergent behavior).","commonSituations":"TLS interception appliance whose CA is not actually being used (so it cannot derive the right keys); faulty middlebox; rare for genuine compliant servers; client/server version skew under unusual GODEBUG TLS flags.","solutions":["Check for and bypass any TLS-intercepting middleware/appliance in the path.","Verify cipher suite and version compatibility with `openssl s_client -connect host:443`.","Remove any GODEBUG TLS flags (e.g. tlsrsakex, tls3des) that force incompatible negotiation.","Confirm the FIPS/non-FIPS build matches on both sides if one is custom."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// You cannot pre-validate the Finished MAC without performing the handshake.\n// Best prevention: ensure a clean, non-intercepted path and compatible crypto policy.\nfunc cleanTLSConfig() *tls.Config {\n    return &tls.Config{MinVersion: tls.VersionTLS12} // no GODEBUG-forced weak suites\n}","typeGuard":"func isFinishedIncorrect(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"server's Finished message was incorrect\")\n}","tryCatchPattern":"if _, err := tls.Dial(\"tcp\", addr, cfg); err != nil {\n    if isFinishedIncorrect(err) {\n        // Likely interception or incompatible crypto; investigate, do not blindly retry.\n        security.ReportHandshakeFailure(addr, err)\n    }\n}","preventionTips":["Audit the path for TLS-intercepting appliances.","Remove GODEBUG TLS flags that force weak/incompatible negotiation.","Verify cipher/version compatibility with openssl s_client.","Treat Finished failures as potential security incidents."],"tags":["tls","security","handshake","integrity"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}