{"record":{"id":"a9ecbf77d130f6a5","repo":"abpframework/abp","slug":"either-region-or-serviceurl-must-be-configured-on","errorCode":null,"errorMessage":"Either Region or ServiceURL must be configured on AwsBlobProviderConfiguration.","messagePattern":"Either Region or ServiceURL must be configured on AwsBlobProviderConfiguration\\.","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"error","filePath":"framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/DefaultAmazonS3ClientFactory.cs","lineNumber":35,"sourceCode":"{\n    protected IDistributedCache<AwsTemporaryCredentialsCacheItem> Cache { get; }\n\n    protected IStringEncryptionService StringEncryptionService { get; }\n\n    public DefaultAmazonS3ClientFactory(\n        IDistributedCache<AwsTemporaryCredentialsCacheItem> cache,\n        IStringEncryptionService stringEncryptionService)\n    {\n        Cache = cache;\n        StringEncryptionService = stringEncryptionService;\n    }\n\n    public virtual async Task<AmazonS3Client> GetAmazonS3Client(\n        AwsBlobProviderConfiguration configuration)\n    {\n        if (configuration.Region.IsNullOrWhiteSpace() && configuration.ServiceURL.IsNullOrWhiteSpace())\n        {\n            throw new AbpException(\n                $\"Either {nameof(AwsBlobProviderConfiguration.Region)} or {nameof(AwsBlobProviderConfiguration.ServiceURL)} must be configured on {nameof(AwsBlobProviderConfiguration)}.\");\n        }\n\n        var region = !configuration.Region.IsNullOrWhiteSpace()\n            ? RegionEndpoint.GetBySystemName(configuration.Region)\n            : null;\n        var clientConfig = await CreateS3ClientConfigAsync(configuration, region);\n\n        if (configuration.UseCredentials)\n        {\n            var awsCredentials = GetAwsCredentials(configuration);\n            return awsCredentials == null\n                ? new AmazonS3Client(clientConfig)\n                : new AmazonS3Client(awsCredentials, clientConfig);\n        }\n\n        if (configuration.UseTemporaryCredentials)\n        {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BlobStoring.Aws/Volo/Abp/BlobStoring/Aws/DefaultAmazonS3ClientFactory.cs#L17-L53","documentation":"Thrown by DefaultAmazonS3ClientFactory.GetAmazonS3Client when neither AwsBlobProviderConfiguration.Region nor ServiceURL is configured (both null/whitespace). The AWS SDK requires at least one to build an AmazonS3Config, so ABP fails fast with an AbpException before constructing the client. Region and ServiceURL are mutually exclusive routing inputs: Region targets an AWS regional endpoint, ServiceURL targets a custom/MinIO endpoint.","triggerScenarios":"Calling any blob operation (Save/Get/Delete/Exists) when the AwsBlobProviderConfiguration has been registered without setting Region or ServiceURL. The factory is invoked on the first operation that needs an AmazonS3Client.","commonSituations":"Configuration loaded from appsettings where the Aws section is missing Region/ServiceURL, using MinIO/LocalStack without setting ServiceURL, environment-specific config not overriding the empty defaults, or a typo in the config key name.","solutions":["Set Region in the Aws blob configuration (e.g. \"us-east-1\") for standard AWS S3.","For MinIO/LocalStack/custom endpoints, set ServiceURL (e.g. \"http://localhost:9000\") instead.","Verify the configuration section is bound (Configure<AwsBlobProviderConfiguration>) and the keys match.","Check that environment-specific appsettings actually override the base values."],"exampleFix":"// before (appsettings.json)\n\"Aws\": {\n  \"AccessKeyId\": \"...\",\n  \"SecretAccessKey\": \"...\"\n}\n\n// after (AWS regional)\n\"Aws\": {\n  \"AccessKeyId\": \"...\",\n  \"SecretAccessKey\": \"...\",\n  \"Region\": \"us-east-1\"\n}\n\n// after (MinIO / custom endpoint)\n\"Aws\": {\n  \"AccessKeyId\": \"...\",\n  \"SecretAccessKey\": \"...\",\n  \"ServiceURL\": \"http://localhost:9000\"\n}","handlingStrategy":"validation","validationCode":"var cfg = serviceProvider.GetRequiredService<IOptions<AwsBlobProviderConfiguration>>().Value;\nif (cfg.Region.IsNullOrWhiteSpace() && cfg.ServiceURL.IsNullOrWhiteSpace())\n{\n    throw new InvalidOperationException(\"Configure AwsBlobProviderConfiguration.Region or ServiceURL.\");\n}","typeGuard":"bool awsEndpointConfigured =\n    !configuration.Region.IsNullOrWhiteSpace() ||\n    !configuration.ServiceURL.IsNullOrWhiteSpace();","tryCatchPattern":"try { await container.SaveAsync(name, stream); }\ncatch (AbpException ex) when (ex.Message.Contains(\"Either Region or ServiceURL\"))\n{ /* fix configuration before retrying */ }","preventionTips":["Always set Region (AWS) or ServiceURL (MinIO/custom) in the Aws configuration section.","Use environment-specific appsettings to override endpoints per environment.","Add a startup health check that validates required blob configuration."],"tags":["aws","configuration","s3","credentials","abp","startup"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}