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

  1. Inspect the wrapped cause (err via errors.GetBase / printing the full chain) — it names the actual field or builder that failed.
  2. Validate the YAML against the current Xray JSON/YAML schema, checking every 'protocol', 'settings' object, and address field.
  3. Reproduce with the equivalent JSON config to confirm which section is broken, then fix that section in the YAML.
  4. 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

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

Related errors


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