XTLS/Xray-core · error
failed to parse yaml config
Error message
failed to parse yaml config
What it means
LoadYAMLConfig decodes a YAML document into the intermediate JSON config structure and then calls Build() to convert it to the protobuf core.Config. This error wraps any failure emitted during that conversion, such as unknown fields, invalid inbound/outbound settings, or a nested builder failing. The '.Base(err)' chain preserves the underlying cause, so the real problem is in the wrapped error, not this message.
Source
Thrown at infra/conf/serial/loader.go:165
}
jsonFile, err := yaml.YAMLToJSON(yamlFile)
if err != nil {
return nil, errors.New("failed to convert yaml to json").Base(err)
}
return DecodeJSONConfig(bytes.NewReader(jsonFile))
}
func LoadYAMLConfig(reader io.Reader) (*core.Config, error) {
yamlConfig, err := DecodeYAMLConfig(reader)
if err != nil {
return nil, err
}
pbConfig, err := yamlConfig.Build()
if err != nil {
return nil, errors.New("failed to parse yaml config").Base(err)
}
return pbConfig, nil
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- Inspect the wrapped cause (err via errors.GetBase / printing the full chain) — it names the actual field or builder that failed.
- Validate the YAML against the current Xray JSON/YAML schema, checking every 'protocol', 'settings' object, and address field.
- Reproduce with the equivalent JSON config to confirm which section is broken, then fix that section in the YAML.
- Check version compatibility: fields from a newer Xray version will fail Build() on an older binary.
Example fix
// before (config.yaml uses an unknown field)
inbounds:
- protocol: dokodemo-door
settings:
addres: 127.0.0.1 # typo, and unknown to builder
// after
inbounds:
- protocol: dokodemo-door
settings:
address: 127.0.0.1
port: 1080 Defensive patterns
Strategy: try-catch
Validate before calling
// Validate YAML maps to expected shape before LoadYAMLConfig
import "gopkg.in/yaml.v3"
func checkYAMLShape(raw []byte) error {
var top map[string]any
if err := yaml.Unmarshal(raw, &top); err != nil {
return err
}
for _, key := range []string{"inbounds", "outbounds"} {
for _, item := range top[key].([]any) {
m := item.(map[string]any)
if _, ok := m["protocol"]; !ok {
return fmt.Errorf("%s entry missing protocol", key)
}
}
}
return nil
} Try / catch
pbConf, err := conf.LoadYAMLConfig(f)
if err != nil {
// Walk the Base chain to surface the real builder failure
log.Fatalf("config load failed: %v", err)
} Prevention
- Lint config in CI with a schema validator before deploy
- Keep a known-good config in version control and diff after edits
- Use JSON configs where tooling/IDE validation is stronger
When it happens
Trigger: Calling infra/conf.LoadYAMLConfig (or LoadConfig with a .yml/.yaml file, or xray run -c config.yaml) where the YAML parses syntactically but contains semantically invalid values: an unknown protocol name, a bad address string, or invalid per-protocol settings that fail during Build().
Common situations: Hand-edited YAML configs with typo'd keys or wrong value types; porting a JSON example to YAML and mangling structure; forgetting that YAML keys are case-sensitive and that 'inbounds'/'outbounds' entries require a valid 'protocol'.
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
- this config must be run on version %s or higher
- this config should be run on version %s or lower
- failed to load config files: [
- failed to create server
- failed to read config: {arg}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/b3d1bffed71854de.
Report an issue: GitHub.