XTLS/Xray-core · error

failed to get shadowsocks user

Error message

failed to get shadowsocks user

What it means

Server-startup error: while converting each configured user via ToMemoryUser() one failed, and this wrapper (AtError severity) aborts NewServer entirely. The base cause is almost always [627]/[626] (unsupported cipher) or a malformed account field, so one bad user prevents the whole Shadowsocks inbound from starting.

Source

Thrown at proxy/shadowsocks/server.go:37

	"github.com/xtls/xray-core/features/routing"
	"github.com/xtls/xray-core/transport/internet/stat"
	"github.com/xtls/xray-core/transport/internet/udp"
)

type Server struct {
	config        *ServerConfig
	validator     *Validator
	policyManager policy.Manager
	cone          bool
}

// NewServer create a new Shadowsocks server.
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
	validator := new(Validator)
	for _, user := range config.Users {
		u, err := user.ToMemoryUser()
		if err != nil {
			return nil, errors.New("failed to get shadowsocks user").Base(err).AtError()
		}

		if err := validator.Add(u); err != nil {
			return nil, errors.New("failed to add user").Base(err).AtError()
		}
	}

	v := core.MustFromContext(ctx)
	s := &Server{
		config:        config,
		validator:     validator,
		policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
		cone:          ctx.Value("cone").(bool),
	}

	return s, nil
}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Find the failing user: run xray run -test or check the log for the base error naming the cipher problem, then fix that user's method/password.
  2. Remove or comment out the offending user to bring the inbound back, then re-add it corrected.
  3. Keep all users on AEAD ciphers on modern Xray.

Example fix

// before: one user breaks the whole inbound
"settings": { "clients": [
  { "method": "aes-256-gcm", "password": "ok" },
  { "method": "aes-256-cfb", "password": "legacy" } ] }
// after
"settings": { "clients": [
  { "method": "aes-256-gcm", "password": "ok" },
  { "method": "aes-256-gcm", "password": "legacy" } ] }
Defensive patterns

Strategy: validation

Validate before calling

for _, u := range config.Users {
  if !isSupportedSSCipher(u.CipherType.String()) {
    return fmt.Errorf("inbound startup blocked by user %q cipher %q", u.Email, u.CipherType)
  }
}

Try / catch

s, err := shadowsocks.NewServer(ctx, cfg)
if err != nil {
  // fail fast, report the offending user from the base error
  log.Error("ss server init failed: ", err)
  return err
}

Prevention

When it happens

Trigger: Building a Shadowsocks server handler from a ServerConfig where any entry in config.Users fails account materialization (bad cipherType, invalid password for the key derivation, missing proto fields).

Common situations: Editing users.json or inbound config by hand; panels injecting a legacy cipher for one user; upgrading Xray after a cipher was removed while old users remain.

Related errors


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