XTLS/Xray-core · error

REALITY: Empty "realitySettings".

Error message

REALITY: Empty "realitySettings".

What it means

Thrown when streamSettings.security is "reality" but no realitySettings object is present. Unlike TLS (which falls back to an empty config), REALITY has no safe defaults — its keys and target must be provided explicitly, so a missing block is a hard error.

Source

Thrown at infra/conf/transport_internet.go:104

	case "", "none":
	case "tls":
		tlsSettings := c.TLSSettings
		if tlsSettings == nil {
			tlsSettings = &TLSConfig{}
		}
		ts, err := tlsSettings.Build()
		if err != nil {
			return nil, errors.New("Failed to build TLS config.").Base(err)
		}
		tm := serial.ToTypedMessage(ts)
		config.SecuritySettings = append(config.SecuritySettings, tm)
		config.SecurityType = tm.Type
	case "reality":
		if config.ProtocolName != "tcp" && config.ProtocolName != "splithttp" && config.ProtocolName != "grpc" {
			return nil, errors.New("REALITY only supports RAW, XHTTP and gRPC for now.")
		}
		if c.REALITYSettings == nil {
			return nil, errors.New(`REALITY: Empty "realitySettings".`)
		}
		ts, err := c.REALITYSettings.Build()
		if err != nil {
			return nil, errors.New("Failed to build REALITY config.").Base(err)
		}
		tm := serial.ToTypedMessage(ts)
		config.SecuritySettings = append(config.SecuritySettings, tm)
		config.SecurityType = tm.Type
	case "xtls":
		return nil, errors.PrintRemovedFeatureError(`Legacy XTLS`, `xtls-rprx-vision with TLS or REALITY`)
	default:
		return nil, errors.New(`Unknown security "` + c.Security + `".`)
	}

	if c.RAWSettings != nil {
		c.TCPSettings = c.RAWSettings
	}
	if c.TCPSettings != nil {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Add a populated "realitySettings" object (publicKey, shortId, serverName, etc.).
  2. Verify the exact key spelling 'realitySettings' and its position inside streamSettings.
  3. Copy the server's REALITY parameters into the client block.

Example fix

// before
"security": "reality"
// after
"security": "reality",
"realitySettings": { "publicKey": "...", "shortId": "...", "serverName": "example.com" }
Defensive patterns

Strategy: type-guard

Validate before calling

if strings.EqualFold(security, "reality") && realitySettings == nil {
    return fmt.Errorf("realitySettings is required when security=reality")
}

Type guard

func hasRealitySettings(s StreamConfigJSON) bool {
    return strings.EqualFold(s.Security, "reality") && s.RealitySettings != nil
}

Prevention

When it happens

Trigger: "security": "reality" with no "realitySettings" key, or with it misspelled (e.g. "reality-settings") so it decodes to nil.

Common situations: Enabling REALITY by only setting the security string; field-name typos; JSON nesting the settings one level too deep.

Related errors


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