{"record":{"id":"fa97a195c20f1e32","repo":"XTLS/Xray-core","slug":"failed-to-decode-config-arg","errorCode":null,"errorMessage":"failed to decode config: {arg}","messagePattern":"failed to decode config: (.+?)","errorType":"validation","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"main/toml/toml.go","lineNumber":32,"sourceCode":")\n\nfunc init() {\n\tcommon.Must(core.RegisterConfigLoader(&core.ConfigFormat{\n\t\tName:      \"TOML\",\n\t\tExtension: []string{\"toml\"},\n\t\tLoader: func(input interface{}) (*core.Config, error) {\n\t\t\tswitch v := input.(type) {\n\t\t\tcase cmdarg.Arg:\n\t\t\t\tcf := &conf.Config{}\n\t\t\t\tfor i, arg := range v {\n\t\t\t\t\terrors.LogInfo(context.Background(), \"Reading config: \", arg)\n\t\t\t\t\tr, err := confloader.LoadConfig(arg)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, errors.New(\"failed to read config: \", arg).Base(err)\n\t\t\t\t\t}\n\t\t\t\t\tc, err := serial.DecodeTOMLConfig(r)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, errors.New(\"failed to decode config: \", arg).Base(err)\n\t\t\t\t\t}\n\t\t\t\t\tif i == 0 {\n\t\t\t\t\t\t// This ensure even if the muti-json parser do not support a setting,\n\t\t\t\t\t\t// It is still respected automatically for the first configure file\n\t\t\t\t\t\t*cf = *c\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tcf.Override(c, arg)\n\t\t\t\t}\n\t\t\t\treturn cf.Build()\n\t\t\tcase io.Reader:\n\t\t\t\treturn serial.LoadTOMLConfig(v)\n\t\t\tdefault:\n\t\t\t\treturn nil, errors.New(\"unknown type\")\n\t\t\t}\n\t\t},\n\t}))\n}","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/main/toml/toml.go#L14-L50","documentation":"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).","triggerScenarios":"Malformed TOML: missing closing bracket in [inbounds...], non-homogeneous array, port as string; or schema mismatch such as nesting settings under the wrong table.","commonSituations":"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.","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"],"exampleFix":"# before\n[[inbounds]]\nport = \"443\"        # string -> failed to decode config\nprotocol = 'dokodemo-door'\n\n# after\n[[inbounds]]\nport = 443\nprotocol = 'dokodemo-door'","handlingStrategy":"validation","validationCode":"// pre-parse with a TOML library before handing to Xray\nvar v map[string]interface{}\nif _, err := toml.DecodeFile(cfgPath, &v); err != nil { log.Fatalf(\"bad TOML: %v\", err) }","typeGuard":null,"tryCatchPattern":"if err := loadToml(); err != nil { if pos := tomlErrPosition(err); pos >= 0 { highlight(cfgPath, pos) }; return err }","preventionTips":["Lint TOML (taplo check) on every commit","Keep types explicit: integers unquoted, real TOML booleans","Generate TOML from tooling rather than editing by hand"],"tags":["go","xray","toml","config","parsing"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}