{"record":{"id":"bd8f3bd26fd95f8b","repo":"tursodatabase/turso","slug":"remote-encryption-cipher-and-remote-encryption-key","errorCode":null,"errorMessage":"Remote Encryption Cipher and Remote Encryption Key must be specified together.","messagePattern":"Remote Encryption Cipher and Remote Encryption Key must be specified together\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoConnectionOptions.cs","lineNumber":117,"sourceCode":"        || HasOption(\"Sync Experimental Features\");\n\n    public bool HasPartialSyncOptions =>\n        HasOption(\"Partial Bootstrap Prefix\")\n        || HasOption(\"Partial Bootstrap Query\")\n        || HasOption(\"Partial Sync Segment Size\")\n        || HasOption(\"Partial Sync Prefetch\");\n\n    public TursoEncryptionCipher? GetEncryptionCipher() => _builder.GetEncryptionCipher();\n\n    public TursoRemoteEncryptionOptions? GetRemoteEncryption()\n    {\n        var cipher = RemoteEncryptionCipher;\n        var key = RemoteEncryptionKey;\n        if (string.IsNullOrWhiteSpace(cipher) && string.IsNullOrWhiteSpace(key))\n            return null;\n        if (string.IsNullOrWhiteSpace(cipher) || string.IsNullOrWhiteSpace(key))\n        {\n            throw new InvalidOperationException(\n                \"Remote Encryption Cipher and Remote Encryption Key must be specified together.\");\n        }\n\n        return new TursoRemoteEncryptionOptions\n        {\n            Cipher = TursoRemoteEncryptionOptions.ParseCipher(cipher),\n            Key = key,\n        };\n    }\n\n    public Uri GetRemoteUri()\n    {\n        if (!Uri.TryCreate(DataSource, UriKind.Absolute, out var uri) || !IsRemoteScheme(uri.Scheme))\n            throw new InvalidOperationException($\"Data Source is not a remote Turso URL: {DataSource}\");\n\n        if (!string.IsNullOrEmpty(uri.Query) || !string.IsNullOrEmpty(uri.Fragment))\n            throw new InvalidOperationException(\"Remote Turso URLs must not include query strings or fragments.\");\n        if (!string.IsNullOrEmpty(uri.UserInfo))","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data/TursoConnectionOptions.cs#L99-L135","documentation":"Remote encryption for embedded replicas requires both a cipher and a key: the replica must know exactly how the remote database is encrypted. GetRemoteEncryption() validates this pair and throws InvalidOperationException when only one of 'Remote Encryption Cipher' or 'Remote Encryption Key' is provided, since a partial pair is always a configuration mistake.","triggerScenarios":"Building TursoConnectionOptions where exactly one of 'Remote Encryption Cipher' or 'Remote Encryption Key' is set (non-whitespace) and the other is missing or empty — evaluated whenever the connection (replica) options are resolved.","commonSituations":"Appending only 'Remote Encryption Key' because the cipher name was unknown; typo'd option name making one half of the pair unreadable; partially edited connection strings when rotating keys.","solutions":["Set both options: 'Remote Encryption Cipher=<cipher>' and 'Remote Encryption Key=<key>'.","Use the same cipher name and key the remote primary was created with, otherwise the replica cannot read replicated pages.","If the remote database is not encrypted, remove both options entirely — one alone is invalid."],"exampleFix":"// before\n\"Data Source=https://mydb.turso.io;Replica Path=replica.db;Remote Encryption Key=secret\"\n// after\n\"Data Source=https://mydb.turso.io;Replica Path=replica.db;Remote Encryption Cipher=aes-256-cbc;Remote Encryption Key=secret\"","handlingStrategy":"validation","validationCode":"var cipher = opts[\"Remote Encryption Cipher\"];\nvar key = opts[\"Remote Encryption Key\"];\nbool hasCipher = !string.IsNullOrWhiteSpace(cipher);\nbool hasKey = !string.IsNullOrWhiteSpace(key);\nif (hasCipher != hasKey)\n    throw new ArgumentException(\"Remote Encryption Cipher and Remote Encryption Key must be set together.\");","typeGuard":"static bool HasCompleteRemoteEncryption(string cipher, string key) =>\n    !string.IsNullOrWhiteSpace(cipher) == !string.IsNullOrWhiteSpace(key);","tryCatchPattern":null,"preventionTips":["Set the pair on one line adjacent in the connection string so one cannot be dropped in edits.","Store cipher and key as a single configuration pair (e.g. one secret entry)."],"tags":["dotnet","encryption","embedded-replica","connection-string"],"backgroundTag":"incomplete-encryption-configuration","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-08-31T11:17:35.598Z","contentChangedAt":"2026-08-31T11:17:35.598Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}