apache/druid · error · IllegalStateException (ISE)

Invalid druid.storage.transfer.asyncHttpClientType[%s]. Must

Error message

Invalid druid.storage.transfer.asyncHttpClientType[%s]. Must be 'crt' or 'netty'.

What it means

AsyncHttpClientType.fromString parses druid.storage.transfer.asyncHttpClientType into the CRT or NETTY enum by case-insensitive name and throws ISE for anything else. The property selects which AWS async HTTP client is used for multipart transfers.

Source

Thrown at extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3StorageDruidModule.java:188

      public SdkAsyncHttpClient.Builder<?> buildBuilder(AWSClientConfig clientConfig)
      {
        return NettyNioAsyncHttpClient.builder()
                                      .connectionTimeout(Duration.ofMillis(clientConfig.getConnectionTimeoutMillis()))
                                      .readTimeout(Duration.ofMillis(clientConfig.getSocketTimeoutMillis()))
                                      .maxConcurrency(clientConfig.getMaxConnections());
      }
    };

    public abstract SdkAsyncHttpClient.Builder<?> buildBuilder(AWSClientConfig clientConfig);

    public static AsyncHttpClientType fromString(String value)
    {
      for (AsyncHttpClientType type : values()) {
        if (type.name().equals(StringUtils.upperCase(value))) {
          return type;
        }
      }
      throw new ISE("Invalid druid.storage.transfer.asyncHttpClientType[%s]. Must be 'crt' or 'netty'.", value);
    }
  }

  @Nullable
  private static URI buildEndpointOverride(AWSEndpointConfig endpointConfig, boolean useHttps)
  {
    if (StringUtils.isNotEmpty(endpointConfig.getUrl())) {
      return URI.create(S3Utils.ensureEndpointHasScheme(endpointConfig.getUrl(), useHttps));
    }
    return null;
  }

  // This provides ServerSideEncryptingAmazonS3 built with all default configs from Guice injection
  /**
   * Creates {@link ServerSideEncryptingAmazonS3} which may perform config validation immediately.
   * You may want to avoid immediate config validation but defer it until you actually use the s3 client.
   * Use {@link #getAmazonS3ClientSupplier} instead in that case.
   */

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Set druid.storage.transfer.asyncHttpClientType to 'crt' or 'netty'.
  2. Remove the property to use the default client.
  3. Ensure the CRT client dependency is on the classpath if choosing 'crt'.

Example fix

// before
druid.storage.transfer.asyncHttpClientType=apache
// after
druid.storage.transfer.asyncHttpClientType=netty
Defensive patterns

Strategy: validation

Validate before calling

String t = props.getProperty("druid.storage.transfer.asyncHttpClientType", "netty");
if (!t.equalsIgnoreCase("crt") && !t.equalsIgnoreCase("netty")) throw new IllegalArgumentException("bad asyncHttpClientType: " + t);

Prevention

When it happens

Trigger: Configuring druid.storage.transfer.asyncHttpClientType to a value other than 'crt' or 'netty' (case-insensitive), e.g. 'apache', 'default', or a typo like 'nett'.

Common situations: Users copying configs from other AWS SDK examples; upgrading Druid where only crt/netty are supported; mixing up this property with the SDK's full HttpClient list.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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