XTLS/Xray-core · error

user account is not valid

Error message

user account is not valid

What it means

Thrown by the trojan client when the configured server user's Account is not a *MemoryAccount (the trojan protocol's internal account type holding the key). This is a programming/registration error: the user object attached to the server spec was built with a different account type than trojan's protocol.RegisterAccount produces.

Source

Thrown at proxy/trojan/client.go:81

		rawConn, err := dialer.Dial(ctx, server.Destination)
		if err != nil {
			return err
		}

		conn = rawConn
		return nil
	})
	if err != nil {
		return errors.New("failed to find an available destination").AtWarning().Base(err)
	}
	errors.LogInfo(ctx, "tunneling request to ", destination, " via ", server.Destination.NetAddr())

	defer conn.Close()

	user := server.User
	account, ok := user.Account.(*MemoryAccount)
	if !ok {
		return errors.New("user account is not valid")
	}

	var newCtx context.Context
	var newCancel context.CancelFunc
	if session.TimeoutOnlyFromContext(ctx) {
		newCtx, newCancel = context.WithCancel(context.Background())
	}

	sessionPolicy := c.policyManager.ForLevel(user.Level)
	ctx, cancel := context.WithCancel(ctx)
	timer := signal.CancelAfterInactivity(ctx, func() {
		cancel()
		if newCancel != nil {
			newCancel()
		}
	}, sessionPolicy.Timeouts.ConnectionIdle)

	postRequest := func() error {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Construct trojan users through the documented path so accounts are parsed via trojan's account registration (config user -> protocol.MemoryAccount with Key derived from password).
  2. If maintaining a fork, keep the type-assert target in sync with the registered account type.
  3. Regenerate the server spec from protobuf (NewServerSpecFromPB) instead of hand-building user objects.
Defensive patterns

Strategy: type-guard

Type guard

func isTrojanMemoryAccount(a interface{}) bool {
	_, ok := a.(*trojan.MemoryAccount)
	return ok
}

Prevention

When it happens

Trigger: server.User.Account type-asserts to *MemoryAccount and fails — e.g. a custom builder inserted a *protocol.AccountUser or a nil/default account, or a fork changed the account type without updating this client.

Common situations: Vendored fork of xray-core where account types were refactored; embedding code constructing ServerSpec users manually with the wrong account implementation; version skew between core and a custom trojan handler.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/5c4afd0267e7b9e4. Report an issue: GitHub.