XTLS/Xray-core · warning
Unable to create Fake Dns Engine
Error message
Unable to create Fake Dns Engine
What it means
Every chunk written must satisfy 1 <= chunkLength <= maxPaddingChunkLength (48 KiB); writePaddingTurnWithBuffer enforces this at write time and sizes its buffer from the max chunk. Both the validation pass (paddingTurnBounds) and defaultPaddingChunks respect this bound, so in the shipped flow this is a defensive invariant against arithmetic bugs or direct calls to the write path with unvalidated variant chunks.
Source
Thrown at app/dns/fakedns/fake.go:61
func (fkdns *Holder) Start() error {
if fkdns.config != nil && fkdns.config.IpPool != "" && fkdns.config.LruSize != 0 {
return fkdns.initializeFromConfig()
}
return errors.New("invalid fakeDNS setting")
}
func (fkdns *Holder) Close() error {
// nothing to do for now, just wait GC
return nil
}
func NewFakeDNSHolder() (*Holder, error) {
var fkdns *Holder
var err error
if fkdns, err = NewFakeDNSHolderConfigOnly(nil); err != nil {
return nil, errors.New("Unable to create Fake Dns Engine").Base(err).AtError()
}
err = fkdns.initialize(dns.FakeIPv4Pool, 65535)
if err != nil {
return nil, err
}
return fkdns, nil
}
func NewFakeDNSHolderConfigOnly(conf *FakeDnsPool) (*Holder, error) {
return &Holder{config: conf}, nil
}
func (fkdns *Holder) initializeFromConfig() error {
return fkdns.initialize(fkdns.config.IpPool, int(fkdns.config.LruSize))
}
func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {
var ipRange *net.IPNetView on GitHub (pinned to 7d214f8b09)
Solutions
- Clamp every variant chunk to [1, 48*1024] before writing
- Split oversized chunks into multiple <= 48 KiB chunks
- Prefer runPaddingSchedule, whose validation reports the offending variant index up front
Example fix
// before
paddingVariant{chunks: []int{100, 0, 50000}}
// after
paddingVariant{chunks: []int{100, 1, 47 * 1024}} Defensive patterns
Strategy: validation
Validate before calling
for _, c := range variant.chunks {
if c < 1 || c > 48*1024 {
return fmt.Errorf("chunk %d out of bounds", c)
}
} Prevention
- Always run runPaddingSchedule validation before writing turns
- Clamp or split generated chunk lists to the 48 KiB cap
When it happens
Trigger: Calling writePaddingTurn/writePaddingTurnWithBuffer directly with variant chunks containing a value <= 0 or > 48 KiB; or a fork changing maxPaddingChunkLength/chunk computation inconsistently.
Common situations: Bypassing runPaddingSchedule in custom transport code; generating variant chunk lists from user data without clamping; integer overflow in custom chunk-splitting helpers.
Related errors
- not a Service.
- Dispatcher: Invalid destination.
- FakeDNSEngine is not initialized, but such a sniffer is used
- Failed to convert address to Net IP.
- unexpected client IP length
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/33cb84fc169f9be1.
Report an issue: GitHub.