{"record":{"id":"26ead73fb5b5b9fc","repo":"XTLS/Xray-core","slug":"reality-empty-realitysettings","errorCode":null,"errorMessage":"REALITY: Empty \"realitySettings\".","messagePattern":"REALITY: Empty \"realitySettings\"\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_internet.go","lineNumber":104,"sourceCode":"\tcase \"\", \"none\":\n\tcase \"tls\":\n\t\ttlsSettings := c.TLSSettings\n\t\tif tlsSettings == nil {\n\t\t\ttlsSettings = &TLSConfig{}\n\t\t}\n\t\tts, err := tlsSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"Failed to build TLS config.\").Base(err)\n\t\t}\n\t\ttm := serial.ToTypedMessage(ts)\n\t\tconfig.SecuritySettings = append(config.SecuritySettings, tm)\n\t\tconfig.SecurityType = tm.Type\n\tcase \"reality\":\n\t\tif config.ProtocolName != \"tcp\" && config.ProtocolName != \"splithttp\" && config.ProtocolName != \"grpc\" {\n\t\t\treturn nil, errors.New(\"REALITY only supports RAW, XHTTP and gRPC for now.\")\n\t\t}\n\t\tif c.REALITYSettings == nil {\n\t\t\treturn nil, errors.New(`REALITY: Empty \"realitySettings\".`)\n\t\t}\n\t\tts, err := c.REALITYSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"Failed to build REALITY config.\").Base(err)\n\t\t}\n\t\ttm := serial.ToTypedMessage(ts)\n\t\tconfig.SecuritySettings = append(config.SecuritySettings, tm)\n\t\tconfig.SecurityType = tm.Type\n\tcase \"xtls\":\n\t\treturn nil, errors.PrintRemovedFeatureError(`Legacy XTLS`, `xtls-rprx-vision with TLS or REALITY`)\n\tdefault:\n\t\treturn nil, errors.New(`Unknown security \"` + c.Security + `\".`)\n\t}\n\n\tif c.RAWSettings != nil {\n\t\tc.TCPSettings = c.RAWSettings\n\t}\n\tif c.TCPSettings != nil {","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_internet.go#L86-L122","documentation":"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.","triggerScenarios":"\"security\": \"reality\" with no \"realitySettings\" key, or with it misspelled (e.g. \"reality-settings\") so it decodes to nil.","commonSituations":"Enabling REALITY by only setting the security string; field-name typos; JSON nesting the settings one level too deep.","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."],"exampleFix":"// before\n\"security\": \"reality\"\n// after\n\"security\": \"reality\",\n\"realitySettings\": { \"publicKey\": \"...\", \"shortId\": \"...\", \"serverName\": \"example.com\" }","handlingStrategy":"type-guard","validationCode":"if strings.EqualFold(security, \"reality\") && realitySettings == nil {\n    return fmt.Errorf(\"realitySettings is required when security=reality\")\n}","typeGuard":"func hasRealitySettings(s StreamConfigJSON) bool {\n    return strings.EqualFold(s.Security, \"reality\") && s.RealitySettings != nil\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["go","xray","config","reality","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}