XTLS/Xray-core · error · errors.Error
failed to decode config: {arg}
Error message
failed to decode config: {arg} What it means
The TOML loader read the input but serial.DecodeTOMLConfig could not unmarshal it into Xray's *conf.Config. TOML syntax errors (bad tables, unterminated strings, invalid value types) and structural mismatches with the config schema produce this; the decoder's message with position info is chained via Base(err).
Source
Thrown at main/toml/toml.go:32
)
func init() {
common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
Name: "TOML",
Extension: []string{"toml"},
Loader: func(input interface{}) (*core.Config, error) {
switch v := input.(type) {
case cmdarg.Arg:
cf := &conf.Config{}
for i, arg := range v {
errors.LogInfo(context.Background(), "Reading config: ", arg)
r, err := confloader.LoadConfig(arg)
if err != nil {
return nil, errors.New("failed to read config: ", arg).Base(err)
}
c, err := serial.DecodeTOMLConfig(r)
if err != nil {
return nil, errors.New("failed to decode config: ", arg).Base(err)
}
if i == 0 {
// This ensure even if the muti-json parser do not support a setting,
// It is still respected automatically for the first configure file
*cf = *c
continue
}
cf.Override(c, arg)
}
return cf.Build()
case io.Reader:
return serial.LoadTOMLConfig(v)
default:
return nil, errors.New("unknown type")
}
},
}))
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Run a TOML validator (taplo check, tomlcheck) to get exact line/column of the syntax error
- Compare table structure with a known-good Xray TOML example; keys map 1:1 with the JSON schema
- Use numbers for ports and booleans as true/false, never quoted
- If conversion keeps failing, keep the config in JSON/YAML which you can validate more easily
Example fix
# before [[inbounds]] port = "443" # string -> failed to decode config protocol = 'dokodemo-door' # after [[inbounds]] port = 443 protocol = 'dokodemo-door'
Defensive patterns
Strategy: validation
Validate before calling
// pre-parse with a TOML library before handing to Xray
var v map[string]interface{}
if _, err := toml.DecodeFile(cfgPath, &v); err != nil { log.Fatalf("bad TOML: %v", err) } Try / catch
if err := loadToml(); err != nil { if pos := tomlErrPosition(err); pos >= 0 { highlight(cfgPath, pos) }; return err } Prevention
- Lint TOML (taplo check) on every commit
- Keep types explicit: integers unquoted, real TOML booleans
- Generate TOML from tooling rather than editing by hand
When it happens
Trigger: Malformed TOML: missing closing bracket in [inbounds...], non-homogeneous array, port as string; or schema mismatch such as nesting settings under the wrong table.
Common situations: Converting JSON configs to TOML by hand and dropping table headers; tabs where TOML requires spaces semantics care; version drift where table/field names changed.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to decode config:
- failed to read config:
- failed to decode config: {arg}
- failed to get outbound handler with tag: ${tag}
- existing tag found: ${tag}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/fa97a195c20f1e32.
Report an issue: GitHub.