hashicorp/terraform · error

refresh Ecs sts token err, fail to get AccessKeySecret

Error message

refresh Ecs sts token err, fail to get AccessKeySecret: %s

What it means

Thrown while refreshing an ECS STS token: JMESPath search for 'AccessKeySecret' errored after AccessKeyId resolved. The Success response object did not expose AccessKeySecret in a shape JMESPath could navigate.

Solutions

  1. Dump the full metadata JSON and confirm AccessKeySecret is present at the top level.
  2. Re-attach or re-select the RAM role on the ECS instance to refresh the credential document.
  3. Update the Alibaba Cloud ECS SDK and this backend to a compatible version.
  4. Rule out middleware truncating the response body.
Defensive patterns

Strategy: validation

Validate before calling

sec, ok := data.(map[string]interface{})["AccessKeySecret"].(string)
if !ok || sec == "" {
    return fmt.Errorf("metadata missing AccessKeySecret")
}

Type guard

func hasAccessKeySecret(v interface{}) bool {
    m, ok := v.(map[string]interface{}); if !ok { return false }
    s, ok := m["AccessKeySecret"].(string); return ok && s != ""
}

Prevention

When it happens

Trigger: Same metadata endpoint returned Success and an AccessKeyId, but the AccessKeySecret field is missing, nested unexpectedly, or the data type for that path is not traversable (e.g., an array element).

Common situations: Partial credential payloads from a degraded metadata service, a RAM role whose temporary credentials are mid-rotation, or an SDK/backend version that parses only some credential fields.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/9a428da8f66ba5c6. Report an issue: GitHub.

Appendix: source

Thrown at internal/backend/remote-state/oss/backend.go:695

		return
	}
	code, err := jmespath.Search("Code", data)
	if err != nil {
		err = fmt.Errorf("refresh Ecs sts token err, fail to get Code: %s", err.Error())
		return
	}
	if code.(string) != "Success" {
		err = fmt.Errorf("refresh Ecs sts token err, Code is not Success")
		return
	}
	accessKeyId, err := jmespath.Search("AccessKeyId", data)
	if err != nil {
		err = fmt.Errorf("refresh Ecs sts token err, fail to get AccessKeyId: %s", err.Error())
		return
	}
	accessKeySecret, err := jmespath.Search("AccessKeySecret", data)
	if err != nil {
		err = fmt.Errorf("refresh Ecs sts token err, fail to get AccessKeySecret: %s", err.Error())
		return
	}
	securityToken, err := jmespath.Search("SecurityToken", data)
	if err != nil {
		err = fmt.Errorf("refresh Ecs sts token err, fail to get SecurityToken: %s", err.Error())
		return
	}

	if accessKeyId == nil || accessKeySecret == nil || securityToken == nil {
		err = fmt.Errorf("there is no any available accesskey, secret and security token for Ecs role %s", ecsRoleName)
		return
	}

	return accessKeyId.(string), accessKeySecret.(string), securityToken.(string), nil
}

func getHttpProxyUrl(rawUrl string) (*url.URL, error) {
	pc := httpproxy.FromEnvironment()

View on GitHub (pinned to d32a084675)