XTLS/Xray-core · warning

failed to find the default "alpn" config

Error message

failed to find the default "alpn" config

What it means

The selected fallback 'name' group has no entry for the negotiated ALPN, and it also lacks an entry with empty ALPN to fall back to. Fallback lookup is nested map[name][alpn][path]; this error means the second level has no default.

Source

Thrown at proxy/trojan/server.go:413

			}
			name = match
		}
	}

	if napfb[name] == nil {
		name = ""
	}
	apfb := napfb[name]
	if apfb == nil {
		return errors.New(`failed to find the default "name" config`).AtWarning()
	}

	if apfb[alpn] == nil {
		alpn = ""
	}
	pfb := apfb[alpn]
	if pfb == nil {
		return errors.New(`failed to find the default "alpn" config`).AtWarning()
	}

	path := ""
	if len(pfb) > 1 || pfb[""] == nil {
		if firstLen >= 18 && first.Byte(4) != '*' { // not h2c
			firstBytes := first.Bytes()
			for i := 4; i <= 8; i++ { // 5 -> 9
				if firstBytes[i] == '/' && firstBytes[i-1] == ' ' {
					search := len(firstBytes)
					if search > 64 {
						search = 64 // up to about 60
					}
					for j := i + 1; j < search; j++ {
						k := firstBytes[j]
						if k == '\r' || k == '\n' { // avoid logging \r or \n
							break
						}
						if k == '?' || k == ' ' {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Add a fallback entry with no 'alpn' key (empty = any ALPN) under the same name
  2. Or explicitly add an entry matching the ALPN you see in logs (commonly h2 and http/1.1)
  3. If you do not want ALPN-based splitting, strip 'alpn' from all fallback entries

Example fix

// json: second entry covers any ALPN for this name
"fallbacks": [
  {"name": "a.example.com", "alpn": "h2", "dest": 8001},
  {"name": "a.example.com", "dest": 8001}
]
Defensive patterns

Strategy: validation

Validate before calling

// ensure each named fallback group has an alpn wildcard
func validateAlpn(fbs []Fallback) error {
    byName := map[string]bool{}
    for _, f := range fbs {
        if f.Name != "" && f.Alpn == "" { byName[f.Name] = true }
    }
    for _, f := range fbs {
        if f.Name != "" && f.Alpn != "" && !byName[f.Name] {
            return errors.New("name '" + f.Name + "' lacks an any-ALPN default")
        }
    }
    return nil
}

Prevention

When it happens

Trigger: TLS was negotiated with an ALPN string (e.g. 'h2') while every fallback under this name specifies a different alpn value, and none has alpn "" (wildcard).

Common situations: Client negotiates h2 but fallbacks were written for http/1.1 only; ALPN strings mismatch exactly (trailing space, case); xtls-rprx-vision style ALPN configured on the client forcing an unexpected value.

Related errors


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