XTLS/Xray-core · error
User ${email} not found.
Error message
User ${email} not found. What it means
Validator.Del found no user registered under the given (lowercased) email — v.email.Load returned nil. Nothing was deleted; the error tells you the key does not match any current user of this trojan inbound.
Source
Thrown at proxy/trojan/validator.go:38
if u.Email != "" {
_, loaded := v.email.LoadOrStore(strings.ToLower(u.Email), u)
if loaded {
return errors.New("User ", u.Email, " already exists.")
}
}
v.users.Store(hexString(u.Account.(*MemoryAccount).Key), u)
return nil
}
// Del a trojan user with a non-empty Email.
func (v *Validator) Del(e string) error {
if e == "" {
return errors.New("Email must not be empty.")
}
le := strings.ToLower(e)
u, _ := v.email.Load(le)
if u == nil {
return errors.New("User ", e, " not found.")
}
v.email.Delete(le)
v.users.Delete(hexString(u.(*protocol.MemoryUser).Account.(*MemoryAccount).Key))
return nil
}
// Get a trojan user with hashed key, nil if user doesn't exist.
func (v *Validator) Get(hash string) *protocol.MemoryUser {
u, _ := v.users.Load(hash)
if u != nil {
return u.(*protocol.MemoryUser)
}
return nil
}
// Get a trojan user with hashed key, nil if user doesn't exist.
func (v *Validator) GetByEmail(email string) *protocol.MemoryUser {
email = strings.ToLower(email)View on GitHub (pinned to 7d214f8b09)
Solutions
- List the inbound's current users (API/config) and use the email exactly as stored
- Make deletion flows tolerate 'not found' as success if idempotency is desired
- Check for whitespace/case drift in the email string before calling Del
Example fix
// tolerate double-delete in automation
if err := validator.Del(email); err != nil && !strings.Contains(err.Error(), "not found") {
return err
}
return nil Defensive patterns
Strategy: try-catch
Validate before calling
// check existence first
func userExists(v *Validator, email string) bool {
u, _ := v.email.Load(strings.ToLower(email))
return u != nil
} Try / catch
if err := v.Del(email); err != nil {
if strings.Contains(err.Error(), "not found") {
return nil // deletion is idempotent
}
return err
} Prevention
- Make remove flows idempotent by treating 'not found' as success
- Normalize emails (trim + lowercase) before any Add/Del call
- Maintain one source of truth for the user list instead of editing config and API state separately
When it happens
Trigger: Deleting an email that was never added, was already deleted (double-remove), or differs in more than case (typo, trailing whitespace, domain change).
Common situations: Idempotent-retry scripts hitting 'already removed' users; stale config drift between what operators think is registered and actual state; emails edited on the client side only.
Related errors
- Email must not be empty.
- User ${email} already exists.
- proxy is not a UserManager
- failed to parse user
- Counter %s already registered.
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/524e924c2eec28bc.
Report an issue: GitHub.