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.IPNet

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Clamp every variant chunk to [1, 48*1024] before writing
  2. Split oversized chunks into multiple <= 48 KiB chunks
  3. 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

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


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