temporalio/temporal · critical
unable to create AWS HTTP client for Elasticsearch: %w
Error message
unable to create AWS HTTP client for Elasticsearch: %w
What it means
When Elasticsearch visibility storage is configured with AWS request signing, ServerOptionsProvider builds a signed-transport HTTP client via esclient.NewAwsHttpClient(esConfig.AWSRequestSigning). Failure (invalid signing config, bad AWS region/credentials setup) is wrapped as 'unable to create AWS HTTP client for Elasticsearch' and prevents server startup.
Source
Thrown at temporal/fx.go:276
if persistenceConfig.SecondaryVisibilityConfigExist() &&
persistenceConfig.DataStores[persistenceConfig.SecondaryVisibilityStore].Elasticsearch != nil {
esConfig = persistenceConfig.DataStores[persistenceConfig.SecondaryVisibilityStore].Elasticsearch
esConfig.SetHttpClient(so.elasticsearchHttpClient)
}
if persistenceConfig.VisibilityConfigExist() &&
persistenceConfig.DataStores[persistenceConfig.VisibilityStore].Elasticsearch != nil {
esConfig = persistenceConfig.DataStores[persistenceConfig.VisibilityStore].Elasticsearch
esConfig.SetHttpClient(so.elasticsearchHttpClient)
}
if esConfig != nil {
esHttpClient := so.elasticsearchHttpClient
if esHttpClient == nil {
var err error
esHttpClient, err = esclient.NewAwsHttpClient(esConfig.AWSRequestSigning)
if err != nil {
return serverOptionsProvider{}, fmt.Errorf("unable to create AWS HTTP client for Elasticsearch: %w", err)
}
}
esClient, err = esclient.NewClient(esConfig, esHttpClient, logger)
if err != nil {
return serverOptionsProvider{}, fmt.Errorf("unable to create Elasticsearch client (URL = %v, username = %q): %w",
esConfig.URL.Redacted(), esConfig.Username, err)
}
}
// check that when static hosts are defined, they are defined for all required hosts
if len(so.hostsByService) > 0 {
for _, service := range DefaultServices {
hosts := so.hostsByService[primitives.ServiceName(service)]
if len(hosts.All) == 0 {
return serverOptionsProvider{}, fmt.Errorf("%w: %v", missingServiceInStaticHosts, service)
}
}View on GitHub (pinned to bde624efd1)
Solutions
- Fix the wrapped inner error: set a valid AWS region and ensure credentials are resolvable (env vars, instance role, shared config)
- Verify the AWSRequestSigning block in the visibility config matches the documented schema (region, and partitionID if required)
- If signing is unnecessary (e.g. VPC-internal ES without auth), remove awsRequestSigning and use basic auth instead
Example fix
// before
visibilityStore:
elasticsearch:
awsRequestSigning:
region: ""
// after
visibilityStore:
elasticsearch:
awsRequestSigning:
region: "us-east-1" Defensive patterns
Strategy: validation
Validate before calling
if sign := esCfg.AWSRequestSigning; sign != nil {
if sign.Region == "" { return fmt.Errorf("awsRequestSigning.region is required") }
if _, err := ec2metadatacreds / chain resolution test; err != nil { return err }
} Prevention
- Set AWS_REGION and verify credentials resolve (aws sts get-caller-identity) before starting the server
- Keep the AWSRequestSigning schema current with the server version's config docs
- Use basic auth instead of request signing when the ES cluster does not require AWS SigV4
When it happens
Trigger: esConfig visibility config with awsRequestSigning set but with an invalid/missing region, malformed signing options, or the AWS credentials chain failing at client construction.
Common situations: AWS-hosted Elasticsearch/OpenSearch without AWS_REGION set; typo in region (e.g. 'us-east-1a'); signing enabled but no credentials provider resolvable; missing v4 signing library configuration after version upgrade.
Related errors
- failed to retrieve AWS credentials: %w
- failed to read request body: %w
- failed to sign request: %w
- unable to resolve AWS region for obtaining AWS Elastic signi
- unable to create metrics handler: %w
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/87cd81caf6303848.
Report an issue: GitHub.