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
- Add a populated "realitySettings" object (publicKey, shortId, serverName, etc.).
- Verify the exact key spelling 'realitySettings' and its position inside streamSettings.
- 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
- Treat security=reality without realitySettings as a schema error in CI.
- Use exact key 'realitySettings' inside streamSettings.
- Generate REALITY blocks from server output instead of hand-editing.
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
- bridge tag is empty
- bridge domain is empty
- portal tag is empty
- portal domain is empty
- unknown action: {}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/26ead73fb5b5b9fc.
Report an issue: GitHub.