XTLS/Xray-core · error
padding turn %d has an invalid write chunk range: %d-%d
Error message
padding turn %d has an invalid write chunk range: %d-%d
What it means
validatePaddingSchedule rejected turn i's generated write-chunk parameters: writeChunkMinLength is negative, writeChunkLength < writeChunkMinLength, or writeChunkLength exceeds maxPaddingChunkLength (48 KiB). These bound the random chunk sizes used when the turn writes padding without explicit variants.
Source
Thrown at transport/internet/finalmask/xmc/padding.go:95
if firstTurnPrefixLength < 0 {
return fmt.Errorf("negative first turn prefix length: %d", firstTurnPrefixLength)
}
if firstTurnPrefixLength > 0 && schedule[0].direction != paddingClientToServer {
return fmt.Errorf("first prefixed padding turn is not client-to-server")
}
for i, turn := range schedule {
if turn.direction != paddingClientToServer && turn.direction != paddingServerToClient {
return fmt.Errorf("padding turn %d has invalid direction: %d", i, turn.direction)
}
if err := validatePaddingDelayRange(turn.startDelay); err != nil {
return fmt.Errorf("padding turn %d has an invalid start delay: %w", i, err)
}
if err := validatePaddingDelayRange(turn.chunkDelay); err != nil {
return fmt.Errorf("padding turn %d has an invalid chunk delay: %w", i, err)
}
if turn.writeChunkMinLength < 0 || turn.writeChunkLength < turn.writeChunkMinLength || turn.writeChunkLength > maxPaddingChunkLength {
return fmt.Errorf("padding turn %d has an invalid write chunk range: %d-%d", i, turn.writeChunkMinLength, turn.writeChunkLength)
}
if len(turn.variants) > 0 && turn.writeChunkLength != 0 {
return fmt.Errorf("padding turn %d combines variants with generated write chunks", i)
}
minLength, maxLength, err := paddingTurnBounds(turn)
if err != nil {
return fmt.Errorf("padding turn %d: %w", i, err)
}
hasSendRange := turn.sendMinLength != 0 || turn.sendMaxLength != 0
if hasSendRange {
if len(turn.variants) > 0 {
return fmt.Errorf("padding turn %d combines variants with a send range", i)
}
if turn.sendMinLength < minLength || turn.sendMaxLength < turn.sendMinLength || turn.sendMaxLength > maxLength {
return fmt.Errorf("padding turn %d has an invalid send range: %d-%d", i, turn.sendMinLength, turn.sendMaxLength)
}
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Set 0 <= writeChunkMinLength <= writeChunkLength <= 48*1024
- Leave both zero to use the default 16 KiB paddingBufferLength chunking
- Clamp externally supplied chunk sizes to maxPaddingChunkLength before building the turn
Example fix
// before writeChunkMinLength: 32 * 1024, writeChunkLength: 64 * 1024 // > 48 KiB cap // after writeChunkMinLength: 32 * 1024, writeChunkLength: 48 * 1024
Defensive patterns
Strategy: validation
Validate before calling
func validWriteChunkRange(minLen, length int) bool {
return minLen >= 0 && length >= minLen && length <= 48*1024
} Prevention
- Clamp chunk sizes to the 48 KiB cap when they come from config
- Leave both values zero to use the safe default chunking
When it happens
Trigger: A turn with writeChunkMinLength < 0, a min greater than the fixed length, or a writeChunkLength above 49152; setting writeChunkLength without clamping to the 48 KiB cap.
Common situations: Forks tuning chunk sizes for different Minecraft versions; config values expressed in the wrong unit (bits vs bytes); off-by-one conversions at the 48 KiB boundary.
Related errors
- empty padding schedule
- negative first turn prefix length: %d
- first prefixed padding turn is not client-to-server
- padding turn %d has invalid direction: %d
- padding turn %d has an invalid start delay: %w
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/228254b11ce19614.
Report an issue: GitHub.