XTLS/Xray-core · error
write padding turn %d: %w
Error message
write padding turn %d: %w
What it means
runPaddingSchedule failed while locally writing padding turn i to imitate Minecraft 1.26.12 traffic shape. The wrapped error is either an I/O failure writing a padding chunk, or a randomness/variant-selection error inside writePaddingTurnWithBuffer (e.g. bad delay range, chunk shorter than the length header).
Source
Thrown at transport/internet/finalmask/xmc/padding.go:62
sendVariants []int
}
func runPaddingSchedule(reader io.Reader, writer io.Writer, isClient bool, firstTurnPrefixLength int, schedule []paddingTurn) error {
if err := validatePaddingSchedule(schedule, firstTurnPrefixLength); err != nil {
return err
}
var writeBuffer []byte
for i, turn := range schedule {
prefixLength := 0
if i == 0 {
prefixLength = firstTurnPrefixLength
}
localSends := isClient == (turn.direction == paddingClientToServer)
if localSends {
if err := writePaddingTurnWithBuffer(writer, turn, prefixLength, time.Sleep, &writeBuffer); err != nil {
return fmt.Errorf("write padding turn %d: %w", i, err)
}
continue
}
if err := readPaddingTurn(reader, turn, prefixLength); err != nil {
return fmt.Errorf("read padding turn %d: %w", i, err)
}
}
return nil
}
func validatePaddingSchedule(schedule []paddingTurn, firstTurnPrefixLength int) error {
if len(schedule) == 0 {
return fmt.Errorf("empty padding schedule")
}
if firstTurnPrefixLength < 0 {
return fmt.Errorf("negative first turn prefix length: %d", firstTurnPrefixLength)
}
if firstTurnPrefixLength > 0 && schedule[0].direction != paddingClientToServer {View on GitHub (pinned to 7d214f8b09)
Solutions
- Check the wrapped error: 'write padding chunk N' indicates transport failure (reconnect); other messages indicate schedule-definition bugs
- If you maintain schedules, run them through validatePaddingSchedule-equivalent checks plus a dry-run writer in tests
- Verify both endpoints use the same hardcoded schedule (same library version)
Defensive patterns
Strategy: try-catch
Try / catch
err := runPaddingSchedule(...)
if err != nil && strings.Contains(err.Error(), "write padding turn") {
// transport died mid-shaping or schedule bug; reconnect or fix schedule
return err
} Prevention
- Dry-run new schedules against an io.Discard writer in tests
- Validate schedule definitions with validatePaddingSchedule before shipping
- Keep both endpoints on the same schedule version
When it happens
Trigger: The local endpoint sends its padding turns and the connection breaks mid-write; the schedule's turn definition is internally inconsistent so chunk generation produces invalid records (code-level bug in the schedule definition).
Common situations: Peer disconnects during the handshake padding phase; firewall RSTs on the bursty padding pattern; custom padding schedules added by forks with invalid chunk/delay parameters.
Related errors
- read padding turn %d: %w
- run startup padding: %w
- write encryption response: %w
- read login finished: %w
- write login acknowledged: %w
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/144f9ebf32117c95.
Report an issue: GitHub.