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

  1. Quote both credentials: {"user":"12345","pass":"secret"}
  2. Use the exact keys "user" and "pass"
  3. 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

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

Related errors


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