{"record":{"id":"042b5b8863d354c7","repo":"XTLS/Xray-core","slug":"trojan-password-is-not-specified","errorCode":null,"errorMessage":"Trojan password is not specified.","messagePattern":"Trojan password is not specified\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/trojan.go","lineNumber":71,"sourceCode":"\t\t\t\tFlow:     c.Flow,\n\t\t\t},\n\t\t}\n\t}\n\tif len(c.Servers) != 1 {\n\t\treturn nil, errors.New(`Trojan settings: \"servers\" should have one and only one member. Multiple endpoints in \"servers\" should use multiple Trojan outbounds and routing balancer instead`)\n\t}\n\n\tconfig := &trojan.ClientConfig{}\n\n\tfor _, rec := range c.Servers {\n\t\tif rec.Address == nil {\n\t\t\treturn nil, errors.New(\"Trojan server address is not set.\")\n\t\t}\n\t\tif rec.Port == 0 {\n\t\t\treturn nil, errors.New(\"Invalid Trojan port.\")\n\t\t}\n\t\tif rec.Password == \"\" {\n\t\t\treturn nil, errors.New(\"Trojan password is not specified.\")\n\t\t}\n\t\tif rec.Flow != \"\" {\n\t\t\treturn nil, errors.PrintRemovedFeatureError(`Flow for Trojan`, ``)\n\t\t}\n\n\t\tconfig.Server = &protocol.ServerEndpoint{\n\t\t\tAddress: rec.Address.Build(),\n\t\t\tPort:    uint32(rec.Port),\n\t\t\tUser: &protocol.User{\n\t\t\t\tLevel: uint32(rec.Level),\n\t\t\t\tEmail: rec.Email,\n\t\t\t\tAccount: serial.ToTypedMessage(&trojan.Account{\n\t\t\t\t\tPassword: rec.Password,\n\t\t\t\t}),\n\t\t\t},\n\t\t}\n\n\t\tbreak","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/trojan.go#L53-L89","documentation":"Thrown when the Trojan server entry's 'password' is an empty string. The Trojan protocol authenticates purely by password hash, so an empty password makes the account unusable and the config is rejected at build time.","triggerScenarios":"A servers entry with no \"password\" key or \"password\": \"\" while building the Trojan outbound.","commonSituations":"Forgetting to fill in the password when templating configs, or the password living only in an env var that was not substituted before Xray read the file.","solutions":["Set \"password\" to the value configured on the Trojan server","If using env substitution, verify the variable resolves before Xray loads the config (xray run -c config.json after substitution)"],"exampleFix":"// before\n{ \"address\": \"trojan.example.com\", \"port\": 443, \"password\": \"\" }\n// after\n{ \"address\": \"trojan.example.com\", \"port\": 443, \"password\": \"your-password\" }","handlingStrategy":"validation","validationCode":"if gjson.Get(serverRaw, \"password\").String() == \"\" {\n    return errors.New(\"trojan server password must not be empty\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check required credentials before config generation, not at runtime","Substitute secrets via environment files and verify non-empty after rendering"],"tags":["config","trojan","password","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}