XTLS/Xray-core · error
failed to parse socks account
Error message
failed to parse socks account
What it means
After decoding the user envelope, Xray unmarshals the same raw JSON object into SocksAccount (infra/conf/socks.go:126-127) to read username/password. If the object's "user"/"pass" fields exist but are not strings (or the entry is not an object at all), config load fails with "failed to parse socks account".
Source
Thrown at infra/conf/socks.go:127
Port: uint32(serverConfig.Port),
}
for _, rawUser := range serverConfig.Users {
user := new(protocol.User)
if v.Address != nil {
user.Level = v.Level
user.Email = v.Email
} else {
if err := json.Unmarshal(rawUser, user); err != nil {
return nil, errors.New("failed to parse Socks user").Base(err).AtError()
}
}
account := new(SocksAccount)
if v.Address != nil {
account.Username = v.Username
account.Password = v.Password
} else {
if err := json.Unmarshal(rawUser, account); err != nil {
return nil, errors.New("failed to parse socks account").Base(err).AtError()
}
}
user.Account = serial.ToTypedMessage(account.Build())
server.User = user
break
}
config.Server = server
break
}
return config, nil
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- Quote both credentials: {"user":"12345","pass":"secret"}
- Use the exact keys "user" and "pass"
- Or switch to the legacy flat settings form {"address",...,"user":"...","pass":"..."} which bypasses raw unmarshaling
Example fix
// before
"users": [ { "user": 12345, "pass": true } ]
// after
"users": [ { "user": "12345", "pass": "true" } ] Defensive patterns
Strategy: validation
Validate before calling
for (const u of server.users ?? []) {
if ('user' in u && typeof u.user !== 'string') throw new Error('socks "user" must be a string');
if ('pass' in u && typeof u.pass !== 'string') throw new Error('socks "pass" must be a string');
} Type guard
const isSocksAccount = (u: unknown): u is {user:string; pass:string} =>
typeof u === 'object' && u !== null &&
(u as any).user === undefined || typeof (u as any).user === 'string' &&
(u as any).pass === undefined || typeof (u as any).pass === 'string'; Try / catch
catch (e) { if (e.message.includes('failed to parse socks account')) { /* check user/pass types in users[i] */ } } Prevention
- Use keys "user" and "pass" with string values only
- Prefer the flat settings form for single-credential outbounds
When it happens
Trigger: A servers[].users[i] object where "user" or "pass" is a number, boolean, object, or null-adjacent mismatch, e.g. {"user":12345,"pass":"x"}. Field names must be exactly "user" and "pass" (not "username"/"password") — wrong names simply leave credentials empty but do not error; wrong types do.
Common situations: Using "username"/"password" keys from another client's docs and then also mis-typing values; auto-generated configs that insert numeric usernames without quoting; mixing inbound account schema ({"user","pass"} per inbound) into outbound users with numeric values.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse Socks user
- invalid fakedns config
- SOCKS servers: "users" should have one member at most. Multi
- unknown type
- failed to read config:
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/5d1cfef864233b2f.
Report an issue: GitHub.