{"record":{"id":"66c5845331787bd0","repo":"XTLS/Xray-core","slug":"run-startup-padding-w","errorCode":null,"errorMessage":"run startup padding: %w","messagePattern":"run startup padding: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/client.go","lineNumber":221,"sourceCode":"\t\treturn fmt.Errorf(\"authentication rejected: %s\", reason)\n\t}\n\tif pkt.packetID != 0x02 {\n\t\treturn fmt.Errorf(\"bad login finished packet id: %d\", pkt.packetID)\n\t}\n\n\treceivedProfile, err := readLoginSuccess(pkt)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read login finished fields: %w\", err)\n\t}\n\tif receivedProfile != selectedProfile {\n\t\treturn fmt.Errorf(\"login profile mismatch\")\n\t}\n\tloginAcknowledgedLength, err := writePacketWithLength(c.writer, 0x03)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write login acknowledged: %w\", err)\n\t}\n\tif err = runPaddingSchedule(c.reader, c.writer, true, loginAcknowledgedLength, c.paddingSchedule); err != nil {\n\t\treturn fmt.Errorf(\"run startup padding: %w\", err)\n\t}\n\n\tpacket := newPacketStream(c.reader, c.writer, true)\n\tc.lifecycleMu.Lock()\n\tif c.closed {\n\t\tc.lifecycleMu.Unlock()\n\t\tpacket.Stop()\n\t\treturn net.ErrClosed\n\t}\n\tc.packet = packet\n\tc.reader = packet\n\tc.writer = packet\n\tc.state = clientStateProxy\n\tc.lifecycleMu.Unlock()\n\n\treturn nil\n}\n","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/client.go#L203-L239","documentation":"The startup padding exchange (runPaddingSchedule) failed after Login Acknowledged. Both sides must exchange a deterministic sequence of padding frames to shape the early traffic; the client drives it with the preselected schedule (newClientPaddingSchedule2612) seeded by the loginAcknowledgedLength. Failure means a read or write inside the schedule errored, or the observed padding bytes disagreed with the expected turn.","triggerScenarios":"First Read/Write on the wrapped conn; fails when the server's padding schedule differs from the client's 2612 profile (version skew), when the server sends unexpected padding sizes, or when the socket errors mid-exchange (reset/timeout/deadline).","commonSituations":"Client and server from different releases whose padding profiles diverged; a server that skips or truncates the padding phase; network truncation of the early encrypted frames.","solutions":["Run the same build/version on both ends so padding schedules match","Check the wrapped error: io errors point at the network, comparison errors at schedule mismatch","Review any changes to newClientPaddingSchedule2612 or the server's mirror when maintaining a fork","Retry on a fresh connection once versions are aligned"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if clientXmcVersion != serverXmcVersion {\n    return errors.New(\"padding schedule skew: align xmc versions before connecting\")\n}","typeGuard":null,"tryCatchPattern":"_, err := conn.Read(buf)\nif err != nil && strings.Contains(err.Error(), \"run startup padding\") {\n    var ne net.Error\n    if errors.As(err, &ne) && ne.Timeout() {\n        return redialWithBackoff()\n    }\n    return fmt.Errorf(\"padding schedule mismatch (version skew?): %w\", err)\n}","preventionTips":["Run matching builds so client/server padding schedules agree","Include the full handshake (padding phase) in integration tests","Treat padding failures with timeout inner errors as retryable; treat comparison failures as version bugs"],"tags":["handshake","padding","version-mismatch","network","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}