{"record":{"id":"9a428da8f66ba5c6","repo":"hashicorp/terraform","slug":"refresh-ecs-sts-token-err-fail-to-get-accesskeyse","errorCode":null,"errorMessage":"refresh Ecs sts token err, fail to get AccessKeySecret: %s","messagePattern":"refresh Ecs sts token err, fail to get AccessKeySecret: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/oss/backend.go","lineNumber":695,"sourceCode":"\t\treturn\n\t}\n\tcode, err := jmespath.Search(\"Code\", data)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"refresh Ecs sts token err, fail to get Code: %s\", err.Error())\n\t\treturn\n\t}\n\tif code.(string) != \"Success\" {\n\t\terr = fmt.Errorf(\"refresh Ecs sts token err, Code is not Success\")\n\t\treturn\n\t}\n\taccessKeyId, err := jmespath.Search(\"AccessKeyId\", data)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"refresh Ecs sts token err, fail to get AccessKeyId: %s\", err.Error())\n\t\treturn\n\t}\n\taccessKeySecret, err := jmespath.Search(\"AccessKeySecret\", data)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"refresh Ecs sts token err, fail to get AccessKeySecret: %s\", err.Error())\n\t\treturn\n\t}\n\tsecurityToken, err := jmespath.Search(\"SecurityToken\", data)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"refresh Ecs sts token err, fail to get SecurityToken: %s\", err.Error())\n\t\treturn\n\t}\n\n\tif accessKeyId == nil || accessKeySecret == nil || securityToken == nil {\n\t\terr = fmt.Errorf(\"there is no any available accesskey, secret and security token for Ecs role %s\", ecsRoleName)\n\t\treturn\n\t}\n\n\treturn accessKeyId.(string), accessKeySecret.(string), securityToken.(string), nil\n}\n\nfunc getHttpProxyUrl(rawUrl string) (*url.URL, error) {\n\tpc := httpproxy.FromEnvironment()","sourceCodeStart":677,"sourceCodeEnd":713,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/oss/backend.go#L677-L713","documentation":"Thrown by getAuthCredentialByEcsRoleName (backend.go:644) when the ECS instance-metadata STS response (from http://100.100.100.200/latest/meta-data/ram/security-credentials/<role>) was valid JSON with Code==\"Success\", but the JMESPath lookup for the AccessKeySecret field failed. This is the credential-refresh path used when the backend authenticates via ecs_role_name instead of static AK/SK. It means the metadata service returned a structurally unexpected payload that lacked the expected secret key.","triggerScenarios":"Calling terraform init/plan/apply with an OSS backend whose auth is ecs_role_name, on an ECS instance whose RAM role STS response omits or mis-names the AccessKeySecret field. The JMESPath Search(\"AccessKeySecret\", data) returns a non-nil error (e.g. the value is an unexpected type or the field is absent in a way jmespath treats as an error).","commonSituations":"The RAM role attached to the ECS instance has no attached policy that grants STS credential issuance; the Alibaba metadata service is mid-deployment returning a partial response; an account-wide metadata schema change; running outside Alibaba Cloud against a mocked metadata endpoint that returns an incomplete body.","solutions":["curl http://100.100.100.200/latest/meta-data/ram/security-credentials/<ROLE> from the ECS instance and confirm the JSON contains a non-empty AccessKeySecret.","Verify the RAM role named by ecs_role_name exists and has at least one trusted policy granting the instance the ability to assume it.","If you do not need ECS role auth, switch the backend to static access_key/secret_key or a named profile to bypass the metadata path entirely.","Restart/reattach the RAM role to the instance (ECS console -> Instance -> RAM Role) so metadata returns a complete credential set."],"exampleFix":"// before (backend config, metadata path broken)\nbackend \"oss\" {\n  bucket = \"tf-state\"\n  ecs_role_name = \"my-role\"\n}\n\n// after: use explicit credentials / profile that do not depend on metadata shape\nbackend \"oss\" {\n  bucket = \"tf-state\"\n  profile = \"prod\"\n}","handlingStrategy":"validation","validationCode":"// Before any terraform op using ecs_role_name, probe the metadata endpoint\n// and assert the field is present, so you fail fast with your own message.\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/jmespath/go-jmespath\"\n)\n\nfunc checkSTS(role string) error {\n\turl := \"http://100.100.100.200/latest/meta-data/ram/security-credentials/\" + role\n\tc := &http.Client{Timeout: 3 * time.Second}\n\tresp, err := c.Get(url)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"metadata unreachable: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\tbody, _ := io.ReadAll(resp.Body)\n\tvar data interface{}\n\tif err := json.Unmarshal(body, &data); err != nil {\n\t\treturn fmt.Errorf(\"metadata not JSON: %w\", err)\n\t}\n\tif v, err := jmespath.Search(\"AccessKeySecret\", data); err != nil || v == nil {\n\t\treturn fmt.Errorf(\"AccessKeySecret missing in STS response\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"// Wrap terraform invocation; treat this as a fatal config error, do not retry.\n// In Go, if you call backend methods directly:\nif _, _, _, err := getAuthCredentialByEcsRoleName(role); err != nil {\n    if strings.Contains(err.Error(), \"AccessKeySecret\") {\n        // stop and surface a config-fix prompt; never auto-retry metadata parse errors\n    }\n}","preventionTips":["Prefer static credentials or a named profile in CI; reserve ecs_role_name for code running on ECS.","Add a startup probe of the metadata endpoint in your instance bootstrap so missing fields surface at boot, not mid-apply.","Pin the RAM role trust policy so only the intended ECS service principal can assume it."],"tags":["alibaba-cloud","oss","ecs-sts","authentication","metadata-service","go"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}