{"record":{"id":"f4ad7d8cab0618d8","repo":"XTLS/Xray-core","slug":"no-target-server-found-f4ad7d","errorCode":null,"errorMessage":"no target server found","messagePattern":"no target server found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/trojan/client.go","lineNumber":32,"sourceCode":"\t\"github.com/xtls/xray-core/common/signal\"\n\t\"github.com/xtls/xray-core/common/task\"\n\tcore \"github.com/xtls/xray-core/core\"\n\t\"github.com/xtls/xray-core/features/policy\"\n\t\"github.com/xtls/xray-core/transport\"\n\t\"github.com/xtls/xray-core/transport/internet\"\n\t\"github.com/xtls/xray-core/transport/internet/stat\"\n)\n\n// Client is a inbound handler for trojan protocol\ntype Client struct {\n\tserver        *protocol.ServerSpec\n\tpolicyManager policy.Manager\n}\n\n// NewClient create a new trojan client.\nfunc NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {\n\tif config.Server == nil {\n\t\treturn nil, errors.New(`no target server found`)\n\t}\n\tserver, err := protocol.NewServerSpecFromPB(config.Server)\n\tif err != nil {\n\t\treturn nil, errors.New(\"failed to get server spec\").Base(err)\n\t}\n\n\tv := core.MustFromContext(ctx)\n\tclient := &Client{\n\t\tserver:        server,\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\treturn client, nil\n}\n\n// Process implements OutboundHandler.Process().\nfunc (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\toutbounds := session.OutboundsFromContext(ctx)\n\tob := outbounds[len(outbounds)-1]","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/trojan/client.go#L14-L50","documentation":"Returned by NewClient for the trojan outbound when the ClientConfig carries no Server field. The trojan client is a pure proxy client — it needs exactly one target server to dial, so a missing server is a hard configuration error.","triggerScenarios":"Creating a trojan outbound handler whose config JSON lacks the \"server\" (address/port) object — e.g. only users or streamSettings were provided.","commonSituations":"Hand-written or panel-generated config that omitted the server block; config migration where the server field was renamed/dropped; YAML-to-JSON conversion losing the nested object.","solutions":["Add the required server object to the trojan outbound settings with address and port.","Validate the config with xray run -test (or -c config.json -format json) before deploying.","If generated by a panel/subscription converter, update it or regenerate the subscription."],"exampleFix":"// before\n{ \"protocol\": \"trojan\", \"settings\": { \"servers\": [] } }\n\n// after\n{ \"protocol\": \"trojan\", \"settings\": { \"servers\": [ { \"address\": \"s.example.com\", \"port\": 443, \"password\": \"...\" } ] } }","handlingStrategy":"validation","validationCode":"func ValidateTrojanOutbound(cfg *trojan.ClientConfig) error {\n\tif cfg.Server == nil {\n\t\treturn errors.New(\"trojan outbound requires settings.servers[0]\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint outbound configs (xray run -test) in CI.","Use typed config structs instead of raw maps when generating configs.","Diff generated configs against a known-good template."],"tags":["trojan","outbound","config","missing-server"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}