XTLS/Xray-core · critical
decode key collision for byte %d and %d
Error message
decode key collision for byte %d and %d
What it means
Thrown by buildTable when two different byte values produce the same packed sorted-hint decode key, i.e. the byte-to-grid mapping would be ambiguous in the decoder. The table builder detects that pattern sets for two bytes overlap on a key and aborts rather than emit an undecodable table. The shuffle order, and therefore collisions, depend on the password seed and the chosen layout.
Source
Thrown at transport/internet/finalmask/sudoku/table.go:421
}
for b := 0; b < 256; b++ {
patList := patterns[order[b]]
if len(patList) == 0 {
return nil, fmt.Errorf("grid %d has no valid clue set", order[b])
}
enc := make([][4]byte, 0, len(patList))
for _, groups := range patList {
hints := [4]byte{
layout.encodeHint(groups[0]),
layout.encodeHint(groups[1]),
layout.encodeHint(groups[2]),
layout.encodeHint(groups[3]),
}
sortedHints := sort4(hints)
key := packKey(sortedHints)
if old, exists := t.decode[key]; exists && old != byte(b) {
return nil, fmt.Errorf("decode key collision for byte %d and %d", old, b)
}
t.decode[key] = byte(b)
enc = append(enc, hints)
}
t.encode[b] = enc
}
return t, nil
}
func getBasePatterns() ([][][4]byte, error) {
basePatternsOnce.Do(func() {
basePatterns, basePatternsErr = buildBasePatterns()
})
return basePatterns, basePatternsErr
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- Change the password; the new shuffle reassigns grids and usually clears the collision.
- Remove customTable to use the default entropy layout, which is validated.
- If the collision reproduces with the default layout, report the password hash/version upstream.
Example fix
// before "password": "secret", "customTable": "vvxxppvv" // after "password": "secret2", "customTable": ""
Defensive patterns
Strategy: retry
Try / catch
for salt := 0; salt < 5; salt++ {
t, err := buildTable(fmt.Sprintf("%s-%d", password, salt), layout)
if err == nil {
return t, nil // use the same salt on both peers
}
if !strings.Contains(err.Error(), "decode key collision") {
return nil, err
}
} Prevention
- Both peers must derive the same table; if you salt the password on retry, mirror it on the other side.
- Validate custom patterns against all 256 bytes in a test before deploying.
When it happens
Trigger: Combining a customTable layout with a particular password such that two grids share an identical sorted 4-hint signature. Custom layouts alter which hint bytes are generated, raising collision probability relative to the default layout.
Common situations: Using an exotic customTable pattern that was never validated against all 256 grids; reusing a password across transport versions whose hint encoding changed.
Related errors
- customTable produced empty padding pool
- invalid sudoku ascii mode: %s
- customTable must be 8 chars, got %d
- customTable has invalid char %q
- customTable must contain exactly 2 x, 2 p and 4 v
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/f0f399c374953390.
Report an issue: GitHub.