{"record":{"id":"18f3c4421b19e8d6","repo":"XTLS/Xray-core","slug":"unsupported-cipher","errorCode":null,"errorMessage":"Unsupported cipher.","messagePattern":"Unsupported cipher\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/shadowsocks/config.go","lineNumber":89,"sourceCode":"\t\treturn &AEADCipher{\n\t\t\tKeyBytes:        32,\n\t\t\tIVBytes:         32,\n\t\t\tAEADAuthCreator: createAesGcm,\n\t\t}, nil\n\tcase CipherType_CHACHA20_POLY1305:\n\t\treturn &AEADCipher{\n\t\t\tKeyBytes:        32,\n\t\t\tIVBytes:         32,\n\t\t\tAEADAuthCreator: createChaCha20Poly1305,\n\t\t}, nil\n\tcase CipherType_XCHACHA20_POLY1305:\n\t\treturn &AEADCipher{\n\t\t\tKeyBytes:        32,\n\t\t\tIVBytes:         32,\n\t\t\tAEADAuthCreator: createXChaCha20Poly1305,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, errors.New(\"Unsupported cipher.\")\n\t}\n}\n\n// AsAccount implements protocol.AsAccount.\nfunc (a *Account) AsAccount() (protocol.Account, error) {\n\tCipher, err := a.getCipher()\n\tif err != nil {\n\t\treturn nil, errors.New(\"failed to get cipher\").Base(err)\n\t}\n\treturn &MemoryAccount{\n\t\tCipher:     Cipher,\n\t\tCipherType: a.CipherType,\n\t\tKey:        passwordToCipherKey([]byte(a.Password), Cipher.KeySize()),\n\t\tPassword:   a.Password,\n\t}, nil\n}\n\n// Cipher is an interface for all Shadowsocks ciphers.","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/shadowsocks/config.go#L71-L107","documentation":"Config-time error from Account.getCipher(): the configured CipherType enum value matched no case in the switch. Xray's protobuf config deserializes unknown numeric cipher values without complaint, so this error is typically the first signal of a typo'd or unsupported method name in the JSON config, or a cipher removed/renamed across Xray versions.","triggerScenarios":"Setting cipherType in a shadowsocks account to a value outside the supported set (legacy stream ciphers like rc4-md5, aes-256-cfb after removal, or a raw number from a mis-generated config); loading a config produced for a fork with extra ciphers.","commonSituations":"Migrating from Shadowsocks-libev or old V2Ray configs using stream ciphers; copy-paste typos ('aes-128-gcm ' with space, 'chacha20-ietf-poly1305' vs 'xchacha20-20-poly1305'); configs written for forks whose enums drifted.","solutions":["Set the method to a supported AEAD value: aes-128-gcm, aes-256-gcm, chacha20-poly1305, or xchacha20-poly1305.","Run xray run -test (or -config with validation) after editing to catch config errors before runtime.","If you need legacy stream ciphers, use a Shadowsocks-libev server or an older fork — current Xray deliberately dropped them.","Regenerate the config rather than hand-editing enum numbers."],"exampleFix":"// before\n{ \"method\": \"aes-256-cfb\", \"password\": \"...\" }\n// after\n{ \"method\": \"aes-256-gcm\", \"password\": \"...\" }","handlingStrategy":"validation","validationCode":"var supportedSSCiphers = map[string]bool{\n  \"aes-128-gcm\": true, \"aes-256-gcm\": true,\n  \"chacha20-poly1305\": true, \"xchacha20-poly1305\": true,\n}\nfunc validateCipher(method string) error {\n  if !supportedSSCiphers[method] {\n    return fmt.Errorf(\"unsupported cipher %q; use an AEAD cipher\", method)\n  }\n  return nil\n}","typeGuard":"func isSupportedSSCipher(m string) bool {\n  switch m {\n  case \"aes-128-gcm\", \"aes-256-gcm\", \"chacha20-poly1305\", \"xchacha20-poly1305\":\n    return true\n  }\n  return false\n}","tryCatchPattern":null,"preventionTips":["Validate config with `xray run -test` in CI before deploy.","Never hand-edit numeric cipher enum values; use method names.","Pin config templates to AEAD ciphers only."],"tags":["shadowsocks","config","cipher","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}