XTLS/Xray-core · error
no target server found
Error message
no target server found
What it means
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.
Source
Thrown at proxy/trojan/client.go:32
"github.com/xtls/xray-core/common/signal"
"github.com/xtls/xray-core/common/task"
core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/policy"
"github.com/xtls/xray-core/transport"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/stat"
)
// Client is a inbound handler for trojan protocol
type Client struct {
server *protocol.ServerSpec
policyManager policy.Manager
}
// NewClient create a new trojan client.
func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
if config.Server == nil {
return nil, errors.New(`no target server found`)
}
server, err := protocol.NewServerSpecFromPB(config.Server)
if err != nil {
return nil, errors.New("failed to get server spec").Base(err)
}
v := core.MustFromContext(ctx)
client := &Client{
server: server,
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
}
return client, nil
}
// Process implements OutboundHandler.Process().
func (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
outbounds := session.OutboundsFromContext(ctx)
ob := outbounds[len(outbounds)-1]View on GitHub (pinned to 7d214f8b09)
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.
Example fix
// before
{ "protocol": "trojan", "settings": { "servers": [] } }
// after
{ "protocol": "trojan", "settings": { "servers": [ { "address": "s.example.com", "port": 443, "password": "..." } ] } } Defensive patterns
Strategy: validation
Validate before calling
func ValidateTrojanOutbound(cfg *trojan.ClientConfig) error {
if cfg.Server == nil {
return errors.New("trojan outbound requires settings.servers[0]")
}
return nil
} Prevention
- 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.
When it happens
Trigger: Creating a trojan outbound handler whose config JSON lacks the "server" (address/port) object — e.g. only users or streamSettings were provided.
Common situations: 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.
Related errors
- Trojan settings: "servers" should have one and only one memb
- failed to get server spec
- failed to get outbound handler with tag: ${tag}
- existing tag found: ${tag}
- unsupported domain strategy: {}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/f4ad7d8cab0618d8.
Report an issue: GitHub.