hashicorp/terraform · error

get Ecs sts token err, httpStatus: %d, message = %s

Error message

get Ecs sts token err, httpStatus: %d, message = %s

What it means

Returned by getAuthCredentialByEcsRoleName when the metadata service responds with a non-200 HTTP status. The message includes the status code and the body content. The metadata service should return 200 for a valid attached RAM role; anything else indicates the role is missing, the instance is unauthorized, or the service is erroring.

Source

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

		err = fmt.Errorf("build sts requests err: %s", err.Error())
		return
	}
	httpClient := &http.Client{}
	httpResponse, err := httpClient.Do(httpRequest)
	if err != nil {
		err = fmt.Errorf("get Ecs sts token err : %s", err.Error())
		return
	}

	response := responses.NewCommonResponse()
	err = responses.Unmarshal(response, httpResponse, "")
	if err != nil {
		err = fmt.Errorf("unmarshal Ecs sts token response err : %s", err.Error())
		return
	}

	if response.GetHttpStatus() != http.StatusOK {
		err = fmt.Errorf("get Ecs sts token err, httpStatus: %d, message = %s", response.GetHttpStatus(), response.GetHttpContentString())
		return
	}
	var data interface{}
	err = json.Unmarshal(response.GetHttpContentBytes(), &data)
	if err != nil {
		err = fmt.Errorf("refresh Ecs sts token err, json.Unmarshal fail: %s", err.Error())
		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)

View on GitHub (pinned to c9def3e214)

Solutions

  1. In the Alibaba Cloud console, confirm the named RAM role is attached to THIS ECS instance.
  2. Verify the role name spelling matches exactly (case-sensitive).
  3. Ensure the RAM role's trust policy allows the ECS service to assume it.
  4. curl http://100.100.100.200/latest/meta-data/ram/security-credentials/<role> to see the exact status/body.
  5. Retry once for transient 5xx; if persistent, fall back to static/STS credentials.

Example fix

# before: role 'app-role' not attached to instance
ecs_role_name = "app-role"

# after: attach 'app-role' to the ECS instance in RAM, then keep:
ecs_role_name = "app-role"
# or, until attached, use static creds:
access_key = "LTAI..."
secret_key = "abc..."
Defensive patterns

Strategy: validation

Validate before calling

func roleAttached(role string) error {
    u := "http://100.100.100.200/latest/meta-data/ram/security-credentials/" + role
    resp, err := http.Get(u)
    if err != nil { return err }
    defer resp.Body.Close()
    if resp.StatusCode != 200 {
        return fmt.Errorf("metadata returned %d for role %q; is it attached?", resp.StatusCode, role)
    }
    return nil
}

Try / catch

if _, err := getAuthCredentialByEcsRoleName(role); err != nil {
    if strings.Contains(err.Error(), "httpStatus") {
        return fmt.Errorf("RAM role %q not attached or unauthorized: %w", role, err)
    }
    return err
}

Prevention

When it happens

Trigger: ecs_role_name names a RAM role that is not attached to the instance (404), the instance has no RAM role at all, the role name is misspelled, or the metadata service returns 5xx during a transient fault.

Common situations: Attaching ecs_role_name in config before actually attaching the RAM role to the ECS instance in the console; role name typo; role attached in a different region/account; metadata service briefly 500s.

Related errors


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