hashicorp/terraform · error

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

Error message

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

What it means

Same getAuthCredentialByEcsRoleName path (backend.go:644), but here the JMESPath lookup for SecurityToken failed after AccessKeySecret succeeded. The STS bearer token is the third credential component returned by the metadata service; without it the OSS SDK cannot sign temporary-credential requests. It indicates the metadata JSON is well-formed enough to find the secret but missing/malformed the SecurityToken value.

Source

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

		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()
	u, err := url.Parse(rawUrl)
	if err != nil {
		return nil, err
	}
	return pc.ProxyFunc()(u)

View on GitHub (pinned to c9def3e214)

Solutions

  1. Inspect the raw metadata JSON and confirm a non-empty SecurityToken field exists.
  2. Ensure the RAM role is configured for STS/temporary credential issuance rather than static key material.
  3. Fall back to an explicit profile or access_key/secret_key in the backend block to avoid the metadata STS path.
  4. Re-grant/replace the RAM role on the ECS instance so a full STS triple is issued.

Example fix

// before
backend "oss" {
  bucket = "tf-state"
  ecs_role_name = "stale-role"
}

// after
backend "oss" {
  bucket = "tf-state"
  access_key = var.ali_key
  secret_key = var.ali_secret
}
Defensive patterns

Strategy: validation

Validate before calling

// Extend the checkSTS helper from error 340 to also assert SecurityToken.
if v, err := jmespath.Search("SecurityToken", data); err != nil || v == nil || v == "" {
    return fmt.Errorf("SecurityToken missing/empty in STS response")
}

Try / catch

// Fatal: do not retry. If you invoke the backend programmatically:
if err != nil && strings.Contains(err.Error(), "fail to get SecurityToken") {
    log.Fatal("STS metadata malformed; switch backend auth to a profile or AK/SK")
}

Prevention

When it happens

Trigger: JMESPath Search("SecurityToken", data) returns an error while processing the STS JSON from the instance metadata endpoint. Occurs when the response has AccessKeyId/AccessKeySecret but the SecurityToken field is absent, null in a non-string form, or the JSON shape differs from the documented response.

Common situations: A RAM role policy that issues long-lived keys rather than STS tokens; metadata response from a custom/legacy role; regional metadata service degradation returning partial tokens; running on a non-ECS host with a hand-crafted metadata stub.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/0b1b6ae0e747ebc5. Report an issue: GitHub.