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

  1. Check the wrapped error: 'write padding chunk N' indicates transport failure (reconnect); other messages indicate schedule-definition bugs
  2. If you maintain schedules, run them through validatePaddingSchedule-equivalent checks plus a dry-run writer in tests
  3. 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

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


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/144f9ebf32117c95. Report an issue: GitHub.