{"record":{"id":"77b46cc12bb3b6f7","repo":"shadowsocks/shadowsocks-windows","slug":"failed-to-finish-preparation","errorCode":null,"errorMessage":"failed to finish preparation","messagePattern":"failed to finish preparation","errorType":"exception","errorClass":"System.Exception","httpStatus":null,"severity":"critical","filePath":"shadowsocks-csharp/Encryption/AEAD/AEADMbedTLSEncryptor.cs","lineNumber":68,"sourceCode":"            }\r\n\r\n            MbedTLS.cipher_init(ctx);\r\n            if (MbedTLS.cipher_setup(ctx, MbedTLS.cipher_info_from_string(_innerLibName)) != 0)\r\n                throw new System.Exception(\"Cannot initialize mbed TLS cipher context\");\r\n\r\n            DeriveSessionKey(isEncrypt ? _encryptSalt : _decryptSalt,\r\n                _Masterkey, _sessionKey);\r\n            CipherSetKey(isEncrypt, _sessionKey);\r\n        }\r\n\r\n        private void CipherSetKey(bool isEncrypt, byte[] key)\r\n        {\r\n            IntPtr ctx = isEncrypt ? _encryptCtx : _decryptCtx;\r\n            int ret = MbedTLS.cipher_setkey(ctx, key, keyLen * 8,\r\n                isEncrypt ? MbedTLS.MBEDTLS_ENCRYPT : MbedTLS.MBEDTLS_DECRYPT);\r\n            if (ret != 0) throw new System.Exception(\"failed to set key\");\r\n            ret = MbedTLS.cipher_reset(ctx);\r\n            if (ret != 0) throw new System.Exception(\"failed to finish preparation\");\r\n        }\r\n\r\n        public override void cipherEncrypt(byte[] plaintext, uint plen, byte[] ciphertext, ref uint clen)\r\n        {\r\n            // buf: all plaintext\r\n            // outbuf: ciphertext + tag\r\n            int ret;\r\n            byte[] tagbuf = new byte[tagLen];\r\n            uint olen = 0;\r\n            switch (_cipher)\r\n            {\r\n                case CIPHER_AES:\r\n                    ret = MbedTLS.cipher_auth_encrypt(_encryptCtx,\r\n                        /* nonce */\r\n                        _encNonce, (uint) nonceLen,\r\n                        /* AD */\r\n                        IntPtr.Zero, 0,\r\n                        /* plain */\r","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/shadowsocks/shadowsocks-windows/blob/891d971682eefcaa2e640258d3b352a3ad3b2233/shadowsocks-csharp/Encryption/AEAD/AEADMbedTLSEncryptor.cs#L50-L86","documentation":"Thrown from CipherSetKey when MbedTLS.cipher_reset returns non-zero, fired after a successful cipher_setkey. cipher_reset finalises the context for use; a failure here is rare and indicates the native context is in an inconsistent state after setkey (often a downstream effect of a partially valid cipher/key combo).","triggerScenarios":"The cipher context entered an error state during setkey that was not caught by its return code; calling InitCipher twice on the same context without proper teardown; native memory corruption from a disposed/reused buffer.","commonSituations":"Reusing an encryptor context across reconnections without resetting state; a native buffer being garbage-collected or overwritten; threading on a non-thread-safe context.","solutions":["Ensure InitCipher is called on a freshly allocated context per session and the context is not shared across threads.","Check that setkey succeeded (error 10) before reset runs — the two are coupled.","Rebuild/replace the native mbedTLS library if resets consistently fail, to rule out library corruption."],"exampleFix":"// before\nret = MbedTLS.cipher_reset(ctx);\nif (ret != 0) throw new System.Exception(\"failed to finish preparation\");\n\n// after\nif (ret != 0)\n    throw new System.Exception($\"failed to finish preparation (ret={ret}, cipher={_innerLibName})\");","handlingStrategy":"try-catch","validationCode":"// Ensure context is fresh per session, not reused\nif (_encryptCtx != IntPtr.Zero) { MbedTLS.cipher_free(_encryptCtx); _encryptCtx = IntPtr.Zero; }","typeGuard":null,"tryCatchPattern":"try { CipherSetKey(isEncrypt, key); /* includes reset */ }\ncatch (Exception ex) when (ex.Message == \"failed to finish preparation\")\n{ /* recreate context from scratch and retry once */ }","preventionTips":["Allocate a new cipher context per session; never share across threads.","Tear down contexts explicitly before reuse.","If reset consistently fails, replace/rebuild the native library."],"tags":["encryption","aead","mbedtls","context","state"],"backgroundTag":null,"analyzedSha":"891d971682eefcaa2e640258d3b352a3ad3b2233","analyzedAt":"2026-08-13T10:12:34.434Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}