apache/iceberg · warning

Cannot assume role to sign REST requests because is not…

Error message

Cannot assume role {} to sign REST requests because {} is not set; falling back to the default credentials provider.

What it means

When AwsProperties is configured with a client assume-role ARN (client.assume-role.arn) to sign REST catalog requests, it also requires client.assume-role.region to build an assume-role credentials provider. If the ARN is set but the region is missing, Iceberg logs this warning and falls back to the default AWS credentials provider instead of assuming the role — requests still proceed, but with different credentials than intended.

Solutions

  1. Set the client.assume-role.region property (e.g. in your Spark/Flink catalog configuration or REST catalog properties) to the AWS region of the role to assume.
  2. Verify the property key spelling matches CLIENT_ASSUME_ROLE_REGION (client.assume-role.region) in your config source.
  3. If you don't need role assumption for REST signing, remove client.assume-role.arn so the default credentials provider is used intentionally and without warnings.
  4. After fixing, restart the job and confirm the warning is gone and requests are signed with the assumed-role credentials.

Example fix

// before
{"type": "rest", "uri": "...", "client.assume-role.arn": "arn:aws:iam::123:role/iceberg"}

// after
{"type": "rest", "uri": "...", "client.assume-role.arn": "arn:aws:iam::123:role/iceberg", "client.assume-role.region": "us-east-1"}
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast if assume-role ARN is set without region, before building the catalog
String arn = catalogProps.get("client.assume-role.arn");
String region = catalogProps.get("client.assume-role.region");
if (arn != null && !arn.isEmpty() && (region == null || region.isEmpty())) {
  throw new IllegalArgumentException("client.assume-role.region must be set when client.assume-role.arn is configured");
}

Prevention

When it happens

Trigger: Setting client.assume-role.arn (clientAssumeRoleArn) in catalog properties for a REST catalog without setting client.assume-role.region (clientAssumeRoleRegion); the credentialsProvider() path then warns and returns DefaultCredentialsProvider instead of assumeRoleCredentialsProvider().

Common situations: Partial migration of catalog config where assume-role ARN was added but the companion region property was overlooked; copying example configs that mention the ARN property only; environments where the region was expected to be inherited from other S3 settings but the REST signing path requires its own explicit value.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/5e5acd0449f5a4a8. Report an issue: GitHub.

Appendix: source

Thrown at aws/src/main/java/org/apache/iceberg/aws/AwsProperties.java:521

      } else {
        return StaticCredentialsProvider.create(
            AwsSessionCredentials.create(accessKeyId, secretAccessKey, sessionToken));
      }
    }

    if (!Strings.isNullOrEmpty(this.clientCredentialsProvider)) {
      return credentialsProvider(this.clientCredentialsProvider);
    }

    // When a role is configured to be assumed (e.g. via AssumeRoleAwsClientFactory), sign requests
    // with the assumed-role credentials so that they do not diverge from the credentials used for
    // S3, Glue, KMS and DynamoDB. See https://github.com/apache/iceberg/issues/16667.
    if (!Strings.isNullOrEmpty(this.clientAssumeRoleArn)) {
      if (!Strings.isNullOrEmpty(this.clientAssumeRoleRegion)) {
        return assumeRoleCredentialsProvider();
      }

      LOG.warn(
          "Cannot assume role {} to sign REST requests because {} is not set; "
              + "falling back to the default credentials provider.",
          this.clientAssumeRoleArn,
          CLIENT_ASSUME_ROLE_REGION);
    }

    // Create a new credential provider for each client
    return DefaultCredentialsProvider.builder().build();
  }

  StsAssumeRoleCredentialsProvider assumeRoleCredentialsProvider() {
    Preconditions.checkNotNull(
        this.clientAssumeRoleRegion,
        "Cannot create StsAssumeRoleCredentialsProvider with null region");
    return StsAssumeRoleCredentialsProvider.builder()
        .stsClient(
            StsClient.builder()
                .applyMutation(httpClientProperties::applyHttpClientConfigurations)

View on GitHub (pinned to 86d9c8fc54)