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

  1. Fix the wrapped inner error: set a valid AWS region and ensure credentials are resolvable (env vars, instance role, shared config)
  2. Verify the AWSRequestSigning block in the visibility config matches the documented schema (region, and partitionID if required)
  3. 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

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


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/87cd81caf6303848. Report an issue: GitHub.