XTLS/Xray-core · error

Shadowsocks password is not specified.

Error message

Shadowsocks password is not specified.

What it means

While building a multi-user Shadowsocks inbound server config, each entry in 'users' must carry a non-empty 'password'. This error is returned from the per-user builder when user.Password is empty, aborting the parallel build of the users array.

Source

Thrown at infra/conf/shadowsocks.go:75

	if C.Contains(shadowaead_2022.List, v.Cipher) {
		return buildShadowsocks2022(v)
	}

	config := new(shadowsocks.ServerConfig)
	config.Network = v.NetworkList.Build()

	if v.Users != nil {
		if len(v.Users) > 0 {
			config.Users = make([]*protocol.User, len(v.Users))
			processUser := func(idx int) error {
				user := v.Users[idx]
				account := &shadowsocks.Account{
					Password:   user.Password,
					CipherType: cipherFromString(user.Cipher),
				}
				if account.Password == "" {
					return errors.New("Shadowsocks password is not specified.")
				}
				if account.CipherType < shadowsocks.CipherType_AES_128_GCM ||
					account.CipherType > shadowsocks.CipherType_XCHACHA20_POLY1305 {
					return errors.New("unsupported cipher method: ", user.Cipher)
				}
				config.Users[idx] = &protocol.User{
					Email:   user.Email,
					Level:   uint32(user.Level),
					Account: serial.ToTypedMessage(account),
				}
				return nil
			}
			if err := task.ParallelForN(len(v.Users), processUser); err != nil {
				return nil, err
			}
		}
	} else {
		account := &shadowsocks.Account{

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Add a non-empty 'password' to every entry of the inbound's 'users' array.
  2. If the config was generated, check the generator's variable source for empty password values.
  3. Verify no user entry accidentally has 'password' misspelled (e.g. 'pass' or 'passphrase').

Example fix

// before
"settings": {
  "users": [
    {"cipher": "aes-128-gcm", "level": 0}
  ]
}

// after
"settings": {
  "users": [
    {"cipher": "aes-128-gcm", "password": "my-secret", "level": 0}
  ]
}
Defensive patterns

Strategy: validation

Validate before calling

func validUsers(users []User) bool {
    for _, u := range users {
        if u.Password == "" {
            return false
        }
    }
    return true
}

Type guard

func hasPassword(u map[string]any) bool {
    p, ok := u["password"].(string)
    return ok && p != ""
}

Prevention

When it happens

Trigger: A Shadowsocks inbound with a 'users' array where at least one element omits 'password' (or sets it to ""): {"password": "", "cipher": "aes-128-gcm"} or a user object with only method/level filled.

Common situations: Copy-pasting user templates and forgetting the password; templating configs (Jinja/Ansible) where the password variable is empty; YAML with a commented-out password line.

Related errors


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