XTLS/Xray-core · error
failed to decode config:
Error message
failed to decode config:
What it means
The JSON loader successfully read the input but serial.DecodeJSONConfig could not parse it into a *conf.Config. This is a syntax-level or structure-level JSON failure: invalid JSON, wrong types for Xray fields, or (when strict mode is enabled via serial.UseStrictJSON in the io.Reader branch) unknown/duplicate fields. The parse error is chained as the Base cause with line/column information.
Source
Thrown at main/json/json.go:32
)
func init() {
common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
Name: "JSON",
Extension: []string{"json"},
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.DecodeJSONConfig(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:
if serial.UseStrictJSON {
cfg, err := serial.DecodeJSONConfigStrict(v)
if err != nil {
return nil, err
}
return cfg.Build()
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Validate the file with a JSON linter: jq empty config.json shows exact line/column of the error
- Remove comments and trailing commas; quote all keys; use numbers for ports
- Cross-check field names/types against Xray's JSON config schema (infra/conf)
- Rename the file to .yaml/.toml only if the content really is that format, so the right loader parses it
Example fix
// before
{
"inbounds": [{ "port": "443", "protocol": "dokodemo-door" }] // port as string, comment
}
// after
{
"inbounds": [{ "port": 443, "protocol": "dokodemo-door" }]
} Defensive patterns
Strategy: validation
Validate before calling
// pre-validate before handing to Xray
if data, err := os.ReadFile(cfgPath); err == nil {
if !json.Valid(data) { log.Fatalf("invalid JSON in %s", cfgPath) }
} Try / catch
if err := load(); err != nil {
var syn *json.SyntaxError
if errors.As(err, &syn) { pointAt(cfgPath, int(syn.Offset)) }
} Prevention
- Run jq empty / jsonlint on every config change
- Reject configs with comments or trailing commas in CI
- Generate configs programmatically (marshal from structs) instead of hand-editing
When it happens
Trigger: Trailing commas, unquoted keys, comments in JSON, mismatched braces in a .json config; or values of the wrong type (string where number expected). With strict mode: fields not defined in the schema, such as legacy v2ray keys removed in Xray.
Common situations: Hand-editing JSON configs and breaking syntax, pasting YAML or TOML snippets into a .json file, port written as string "443" instead of number, or migrating configs between v2ray and Xray with incompatible keys.
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
- invalid fakedns config
- failed to parse HTTP user
- failed to parse HTTP account
- failed to parse Socks user
- failed to parse socks account
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/57c119514df89636.
Report an issue: GitHub.