XTLS/Xray-core · error

failed to get cipher

Error message

failed to get cipher

What it means

Wrapper produced by Account.AsAccount() when getCipher() fails, i.e. always directly above [626]. It converts the raw 'Unsupported cipher.' error into an account-construction failure. Any component materializing a Shadowsocks account (server startup, dynamic user add, client outbound init) surfaces this instead of the bare cipher error.

Source

Thrown at proxy/shadowsocks/config.go:97

			IVBytes:         32,
			AEADAuthCreator: createChaCha20Poly1305,
		}, nil
	case CipherType_XCHACHA20_POLY1305:
		return &AEADCipher{
			KeyBytes:        32,
			IVBytes:         32,
			AEADAuthCreator: createXChaCha20Poly1305,
		}, nil
	default:
		return nil, errors.New("Unsupported cipher.")
	}
}

// AsAccount implements protocol.AsAccount.
func (a *Account) AsAccount() (protocol.Account, error) {
	Cipher, err := a.getCipher()
	if err != nil {
		return nil, errors.New("failed to get cipher").Base(err)
	}
	return &MemoryAccount{
		Cipher:     Cipher,
		CipherType: a.CipherType,
		Key:        passwordToCipherKey([]byte(a.Password), Cipher.KeySize()),
		Password:   a.Password,
	}, nil
}

// Cipher is an interface for all Shadowsocks ciphers.
type Cipher interface {
	KeySize() int32
	IVSize() int32
	NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error)
	NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error)
	IsAEAD() bool
	EncodePacket(key []byte, b *buf.Buffer) error
	DecodePacket(key []byte, b *buf.Buffer) error

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Fix the cipher/method of the offending account as in [626] — this error has no independent cause.
  2. When adding users via API, validate the method against the supported list before issuing the request.
  3. In multi-user inbounds, locate the single bad entry (error usually surfaces per-user) and correct or remove it.

Example fix

// before: API payload
{ "email": "u1", "method": "rc4-md5", "password": "x" }
// after
{ "email": "u1", "method": "aes-128-gcm", "password": "x" }
Defensive patterns

Strategy: validation

Validate before calling

// validate every account before calling ToMemoryUser/AsAccount
for _, u := range users {
  if !isSupportedSSCipher(u.Method) {
    return fmt.Errorf("user %s: unsupported cipher %q", u.Email, u.Method)
  }
}

Type guard

func isSupportedSSCipher(m string) bool { /* see error 626 */ return false }

Try / catch

if _, err := account.AsAccount(); err != nil {
  return fmt.Errorf("account %s unusable: %w", account.Password[:0], err) // log base cause, fix cipher
}

Prevention

When it happens

Trigger: user.ToMemoryUser() / AsAccount() invoked on an account whose cipherType is unsupported — server NewServer, handler AddUser (API-driven user management), or client proxy creation.

Common situations: Adding users via the Xray API with a payload copied from an old config; panel/management tool (3x-ui style) sending a removed cipher; one bad user in a batch blocking whole inbound startup.

Related errors


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