apache/druid · critical · ISE

Either set 'key' or 'sharedAccessStorageToken' or 'useAzureC

Error message

Either set 'key' or 'sharedAccessStorageToken' or 'useAzureCredentialsChain' in the azure config. Please refer to azure documentation.

What it means

AzureAccountConfig requires credentials: either a shared key, a SAS token, or opting into the DefaultAzureCredentialChain. If all three (druid.azure.key, druid.azure.sharedAccessStorageToken, druid.azure.useAzureCredentialsChain) are unset/empty, getAzureClientFactory throws this ISE at startup.

Source

Thrown at extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureStorageDruidModule.java:123

                       .build(AzureEntityFactory.class));
    binder.install(new FactoryModuleBuilder()
                       .build(AzureCloudBlobIteratorFactory.class));
    binder.install(new FactoryModuleBuilder()
                       .build(AzureCloudBlobIterableFactory.class));
  }


  @Provides
  @LazySingleton
  public AzureClientFactory getAzureClientFactory(final AzureAccountConfig config)
  {
    if (StringUtils.isEmpty(config.getAccount())) {
      throw new ISE("Set 'account' to the storage account that needs to be configured in the azure config."
          + " Please refer to azure documentation.");
    }

    if (StringUtils.isEmpty(config.getKey()) && StringUtils.isEmpty(config.getSharedAccessStorageToken()) && BooleanUtils.isNotTrue(config.getUseAzureCredentialsChain())) {
      throw new ISE("Either set 'key' or 'sharedAccessStorageToken' or 'useAzureCredentialsChain' in the azure config."
          + " Please refer to azure documentation.");
    }

    /* Azure named keys and sas tokens are mutually exclusive with each other and with azure keychain auth,
    but any form of auth supported by the DefaultAzureCredentialChain is not mutually exclusive, e.g. you can have
    environment credentials or workload credentials or managed credentials using the same chain.
    **/
    if (!StringUtils.isEmpty(config.getKey()) && !StringUtils.isEmpty(config.getSharedAccessStorageToken()) ||
        !StringUtils.isEmpty(config.getKey()) && BooleanUtils.isTrue(config.getUseAzureCredentialsChain()) ||
        !StringUtils.isEmpty(config.getSharedAccessStorageToken()) && BooleanUtils.isTrue(config.getUseAzureCredentialsChain())
    ) {
      throw new ISE("Set only one of 'key' or 'sharedAccessStorageToken' or 'useAzureCredentialsChain' in the azure config."
          + " Please refer to azure documentation.");
    }
    return new AzureClientFactory(config);
  }

  @Provides

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Set druid.azure.key to the storage account key (simplest fix)
  2. Or set druid.azure.sharedAccessStorageToken to a valid SAS token
  3. Or set druid.azure.useAzureCredentialsChain=true and ensure a DefaultAzureCredentialChain source (env vars, managed identity, az CLI) is available
  4. Verify the combination is mutually exclusive as documented — don't set key and SAS token together

Example fix

// before
druid.azure.account=mystorageaccount
// after
druid.azure.account=mystorageaccount
druid.azure.key=<account-key>
# or: druid.azure.useAzureCredentialsChain=true
Defensive patterns

Strategy: validation

Validate before calling

boolean hasAuth = notEmpty(props.get("druid.azure.key"))
    || notEmpty(props.get("druid.azure.sharedAccessStorageToken"))
    || Boolean.parseBoolean(props.getOrDefault("druid.azure.useAzureCredentialsChain", "false"));
if (!hasAuth) throw new IllegalStateException("Configure azure key, SAS token, or credentials chain");

Try / catch

try { injector.getInstance(AzureClientFactory.class); } catch (ProvisionException e) { log.error("Azure auth config missing: %s", e.getMessage()); }

Prevention

When it happens

Trigger: Provisioning the AzureClientFactory when key, sharedAccessStorageToken are empty AND useAzureCredentialsChain is not true — i.e. no authentication method configured.

Common situations: Setting only druid.azure.account and forgetting credentials; removing a key for security migration but not enabling the credentials chain; running in an environment without Azure managed identity while expecting chain auth.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/4f11f30ca212581b. Report an issue: GitHub.