{"record":{"id":"e4995fb25249f23b","repo":"microsoft/garnet","slug":"cannot-use-azurestorage-device-without-supplying-s","errorCode":null,"errorMessage":"Cannot use AzureStorage device without supplying storage-string or storage-service-uri","messagePattern":"Cannot use AzureStorage device without supplying storage-string or storage-service-uri","errorType":"validation","errorClass":"InvalidAzureConfiguration","httpStatus":null,"severity":"critical","filePath":"libs/host/Configuration/Options.cs","lineNumber":755,"sourceCode":"            return isValid;\n        }\n\n        public GarnetServerOptions GetServerOptions(ILogger logger = null)\n        {\n            var enableStorageTier = EnableStorageTier.GetValueOrDefault();\n            var enableRevivification = EnableRevivification.GetValueOrDefault();\n\n            if (UseNativeDeviceLinux.GetValueOrDefault())\n            {\n                logger?.LogWarning(\"The --use-native-device-linux option is deprecated. Please use --device-type Native instead.\");\n                DeviceType = DeviceType.Native;\n            }\n\n            var deviceType = GetDeviceType(logger);\n\n            var useAzureStorage = deviceType == DeviceType.AzureStorage;\n            if (useAzureStorage && string.IsNullOrEmpty(AzureStorageConnectionString) && string.IsNullOrEmpty(AzureStorageServiceUri))\n                throw new InvalidAzureConfiguration(\"Cannot use AzureStorage device without supplying storage-string or storage-service-uri\");\n            if (useAzureStorage && !string.IsNullOrEmpty(AzureStorageConnectionString) && !string.IsNullOrEmpty(AzureStorageServiceUri))\n                throw new InvalidAzureConfiguration(\"Cannot use AzureStorage device with both storage-string and storage-service-uri\");\n\n            var logDir = LogDir;\n            if (!useAzureStorage && enableStorageTier) logDir = new DirectoryInfo(string.IsNullOrEmpty(logDir) ? \".\" : logDir).FullName;\n            var checkpointDir = CheckpointDir;\n            if (!useAzureStorage) checkpointDir = new DirectoryInfo(string.IsNullOrEmpty(checkpointDir) ? (string.IsNullOrEmpty(logDir) ? \".\" : logDir) : checkpointDir).FullName;\n\n            if (!Format.TryParseAddressList(Address, Port, out var endpoints, out _, ProtectedMode == CommandLineBooleanOption.True)\n              || endpoints.Length == 0)\n                throw new GarnetException($\"Invalid endpoint format {Address} {Port}.\");\n\n            EndPoint[] clusterAnnounceEndpoint = null;\n            if (ClusterAnnounceIp != null)\n            {\n                ClusterAnnouncePort = ClusterAnnouncePort == 0 ? Port : ClusterAnnouncePort;\n                clusterAnnounceEndpoint = Format.TryCreateEndpoint(ClusterAnnounceIp, ClusterAnnouncePort, tryConnect: false, logger: logger);\n                if (clusterAnnounceEndpoint == null || !endpoints.Any(endpoint =>","sourceCodeStart":737,"sourceCodeEnd":773,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/host/Configuration/Options.cs#L737-L773","documentation":"InvalidAzureConfiguration thrown during Options.Initialize when the device type is AzureStorage but neither AzureStorageConnectionString nor AzureStorageServiceUri is provided. The Azure storage device factory needs at least one credential source; with neither, it cannot authenticate. This is a startup configuration guard that fires before any network listener is created.","triggerScenarios":"Setting --device-type AzureStorage (or DeviceType = DeviceType.AzureStorage) in the Options without supplying --storage-string (AzureStorageConnectionString) or --storage-service-uri (AzureStorageServiceUri). Typical in cloud deployments where the connection string is expected from an environment variable or key vault that was not wired up.","commonSituations":"Deploying to Azure with device-type AzureStorage but forgetting to set the storage connection string env var; key vault reference not resolved; managed identity intended but the service-URI option used instead was also omitted; copy-paste config that dropped the storage-string line.","solutions":["Provide either --storage-string with a valid Azure Storage connection string, or --storage-service-uri with a blob service URI (used with managed identity).","Verify the environment variable or config field feeding AzureStorageConnectionString is populated in the deployment environment.","If using managed identity, set AzureStorageServiceUri (and optionally AzureStorageManagedIdentity) and leave the connection string empty.","If Azure storage is not actually needed, switch device-type back to local (e.g., Native or Emulated)."],"exampleFix":"// before\noptions.DeviceType = DeviceType.AzureStorage;\n// no storage-string or service-uri set\n\n// after\noptions.DeviceType = DeviceType.AzureStorage;\noptions.AzureStorageConnectionString = Environment.GetEnvironmentVariable(\"AZURE_STORAGE_CONN_STRING\");","handlingStrategy":"validation","validationCode":"void ValidateAzureConfig(Options opts)\n{\n    var useAzure = opts.DeviceType == DeviceType.AzureStorage;\n    if (useAzure && string.IsNullOrEmpty(opts.AzureStorageConnectionString) && string.IsNullOrEmpty(opts.AzureStorageServiceUri))\n        throw new InvalidOperationException(\"AzureStorage device requires --storage-string or --storage-service-uri.\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    options.Initialize(logger);\n}\ncatch (InvalidAzureConfiguration ex)\n{\n    logger.LogCritical(ex, \"Azure storage configuration is incomplete. Set the storage connection string or service URI.\");\n    throw;\n}","preventionTips":["Validate Azure credentials at config-load time before calling Options.Initialize.","Wire storage credentials from a key vault or secret manager so they are never empty at runtime.","Use a startup config validator that checks device-type/credential consistency."],"tags":["config","azure-storage","startup","credentials","options","validation"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}