XTLS/Xray-core · error

tries to resolve itself!

Error message

tries to resolve itself!

What it means

In selectPaddingVariant, after randomly choosing an entry from turn.sendVariants (or the implicit all-indices list), the referenced variant index must satisfy 0 <= index < len(turn.variants). An out-of-range entry means sendVariants contains an index pointing at a variant that does not exist. paddingTurnBounds performs the same check during validation, so hitting this at runtime implies the write path was entered without prior validation (e.g. direct writePaddingTurn calls) or schedules were mutated after validation.

Source

Thrown at app/dns/nameserver_doh.go:140

}

func (s *DoHNameServer) newReqID() uint16 {
	return 0
}

// getCacheController implements CachedNameserver.
func (s *DoHNameServer) getCacheController() *CacheController {
	return s.cacheController
}

// sendQuery implements CachedNameserver.
func (s *DoHNameServer) sendQuery(ctx context.Context, noResponseErrCh chan<- error, fqdn string, option dns_feature.IPOption) {
	errors.LogInfo(ctx, s.Name(), " querying: ", fqdn)

	if s.Name()+"." == "DOH//"+fqdn {
		errors.LogError(ctx, s.Name(), " tries to resolve itself! Use IP or set \"hosts\" instead")
		if noResponseErrCh != nil {
			err := errors.New("tries to resolve itself!", s.Name())
			if option.IPv4Enable {
				noResponseErrCh <- err
			}
			if option.IPv6Enable {
				noResponseErrCh <- err
			}
		}
		return
	}

	// As we don't want our traffic pattern looks like DoH, we use Random-Length Padding instead of Block-Length Padding recommended in RFC 8467
	// Although DoH server like 1.1.1.1 will pad the response to Block-Length 468, at least it is better than no padding for response at all
	reqs, err := buildReqMsgs(fqdn, option, s.newReqID, genEDNS0Options(s.clientIP, int(crypto.RandBetween(100, 300))))
	if err != nil {
		errors.LogErrorInner(ctx, err, "failed to build dns query for ", fqdn)
		if noResponseErrCh != nil {
			if option.IPv4Enable {
				noResponseErrCh <- err

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Ensure every sendVariants entry is within [0, len(variants)-1]
  2. Prefer omitting sendVariants entirely (all variants are then selectable safely)
  3. Run validatePaddingSchedule before writing so the bad index is reported deterministically with context

Example fix

// before
variants: []paddingVariant{v0, v1},
sendVariants: []int{0, 2},
// after
variants: []paddingVariant{v0, v1},
sendVariants: []int{0, 1},
Defensive patterns

Strategy: validation

Validate before calling

for _, idx := range turn.sendVariants {
    if idx < 0 || idx >= len(turn.variants) {
        return fmt.Errorf("send variant index %d out of range", idx)
    }
}

Prevention

When it happens

Trigger: A paddingTurn with sendVariants like [3] while variants has 2 entries, written via writePaddingTurn directly; or schedule slices shared and mutated between validation and the write loop.

Common situations: Custom code composing turns programmatically with off-by-one indices; negative indices from unchecked config parsing; refactoring a variant list without updating the sendVariants index list.

Related errors


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