XTLS/Xray-core · error
FakeDNSEngine is not initialized, but such a sniffer is used
Error message
FakeDNSEngine is not initialized, but such a sniffer is used
What it means
The first padding turn must carry the protocol prefix (e.g. an early data / auth tag) followed by at least one byte of real padding record, so validatePaddingSchedule requires schedule[0]'s minimum total length to exceed firstTurnPrefixLength. If minLength - firstTurnPrefixLength < 1, the smallest possible turn cannot hold even one record byte and the schedule is rejected.
Source
Thrown at app/dispatcher/fakednssniffer.go:26
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/dns"
)
// newFakeDNSSniffer Creates a Fake DNS metadata sniffer
func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error) {
var fakeDNSEngine dns.FakeDNSEngine
{
fakeDNSEngineFeat := core.MustFromContext(ctx).GetFeature((*dns.FakeDNSEngine)(nil))
if fakeDNSEngineFeat != nil {
fakeDNSEngine = fakeDNSEngineFeat.(dns.FakeDNSEngine)
}
}
if fakeDNSEngine == nil {
errNotInit := errors.New("FakeDNSEngine is not initialized, but such a sniffer is used").AtError()
return protocolSnifferWithMetadata{}, errNotInit
}
return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {
outbounds := session.OutboundsFromContext(ctx)
ob := outbounds[len(outbounds)-1]
if ob.Target.Network == net.Network_TCP || ob.Target.Network == net.Network_UDP {
domainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(ob.Target.Address)
if domainFromFakeDNS != "" {
errors.LogInfo(ctx, "fake dns got domain: ", domainFromFakeDNS, " for ip: ", ob.Target.Address.String())
return &fakeDNSSniffResult{domainName: domainFromFakeDNS}, nil
}
}
if ipAddressInRangeValueI := ctx.Value(ipAddressInRange); ipAddressInRangeValueI != nil {
ipAddressInRangeValue := ipAddressInRangeValueI.(*ipAddressInRangeOpt)
if fkr0, ok := fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {
inPool := fkr0.IsIPInIPPool(ob.Target.Address)
ipAddressInRangeValue.addressInRange = &inPoolView on GitHub (pinned to 7d214f8b09)
Solutions
- Increase turn 0 minLength so it is at least firstTurnPrefixLength + 1
- Or reduce firstTurnPrefixLength (e.g. smaller/no early data) if the prefix is under your control
- Verify both peers use matching prefix expectations for the first turn
Example fix
// before
runPaddingSchedule(r, w, true, 64, []paddingTurn{{
direction: paddingClientToServer, minLength: 64, maxLength: 128,
}})
// after
runPaddingSchedule(r, w, true, 64, []paddingTurn{{
direction: paddingClientToServer, minLength: 65, maxLength: 128,
}}) Defensive patterns
Strategy: validation
Validate before calling
if len(schedule) > 0 && schedule[0].minLength-firstTurnPrefixLength < 1 {
return fmt.Errorf("first turn must exceed prefix %d", firstTurnPrefixLength)
} Prevention
- Keep firstTurnPrefixLength and schedule[0] bounds in the same config block so they change together
- When enabling early data, re-check turn 0 minLength >= prefix + 1
When it happens
Trigger: firstTurnPrefixLength >= minLength of turn 0 (e.g. prefix 100 with minLength 100 or 99). Triggered by runPaddingSchedule with a non-zero prefix and a short first turn; fails during up-front validation.
Common situations: Enabling 0-RTT / early data (which raises the prefix length) without enlarging the first turn's minLength; hand-tuning minLength down for smaller overhead; a server profile with a large prefix paired with a client's short-turn schedule.
Related errors
- Failed to convert address to Net IP.
- not a Service.
- Dispatcher: Invalid destination.
- unexpected client IP length
- failed to create hosts
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/2ea38312a2dd1525.
Report an issue: GitHub.