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
- Set druid.storage.transfer.asyncHttpClientType to 'crt' or 'netty'.
- Remove the property to use the default client.
- 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
- Only use 'crt' or 'netty'
- Default (omit the property) if unsure
- Ensure the CRT dependency exists when choosing crt
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
- Failed to get object summaries from S3 bucket[%s], prefix[%s
- Couldn't delete segments from S3. See the task logs for more
- Couldn't kill segment[%s]: [%s]
- Cannot delete all segment from S3 Deep Storage since druid.s
- Target S3 bucket is not specified
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/b7ecd1f461909975.
Report an issue: GitHub.