XTLS/Xray-core · error
run startup padding: %w
Error message
run startup padding: %w
What it means
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.
Source
Thrown at transport/internet/finalmask/xmc/client.go:221
return fmt.Errorf("authentication rejected: %s", reason)
}
if pkt.packetID != 0x02 {
return fmt.Errorf("bad login finished packet id: %d", pkt.packetID)
}
receivedProfile, err := readLoginSuccess(pkt)
if err != nil {
return fmt.Errorf("read login finished fields: %w", err)
}
if receivedProfile != selectedProfile {
return fmt.Errorf("login profile mismatch")
}
loginAcknowledgedLength, err := writePacketWithLength(c.writer, 0x03)
if err != nil {
return fmt.Errorf("write login acknowledged: %w", err)
}
if err = runPaddingSchedule(c.reader, c.writer, true, loginAcknowledgedLength, c.paddingSchedule); err != nil {
return fmt.Errorf("run startup padding: %w", err)
}
packet := newPacketStream(c.reader, c.writer, true)
c.lifecycleMu.Lock()
if c.closed {
c.lifecycleMu.Unlock()
packet.Stop()
return net.ErrClosed
}
c.packet = packet
c.reader = packet
c.writer = packet
c.state = clientStateProxy
c.lifecycleMu.Unlock()
return nil
}
View on GitHub (pinned to 7d214f8b09)
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
Defensive patterns
Strategy: validation
Validate before calling
if clientXmcVersion != serverXmcVersion {
return errors.New("padding schedule skew: align xmc versions before connecting")
} Try / catch
_, err := conn.Read(buf)
if err != nil && strings.Contains(err.Error(), "run startup padding") {
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() {
return redialWithBackoff()
}
return fmt.Errorf("padding schedule mismatch (version skew?): %w", err)
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- write padding turn %d: %w
- read padding turn %d: %w
- write encryption response: %w
- read login finished: %w
- bad login finished packet id: %d
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/66c5845331787bd0.
Report an issue: GitHub.