{"record":{"id":"e903c542bf8471df","repo":"hashicorp/terraform","slug":"refresh-ecs-sts-token-err-json-unmarshal-fail-s","errorCode":null,"errorMessage":"refresh Ecs sts token err, json.Unmarshal fail: %s","messagePattern":"refresh Ecs sts token err, json\\.Unmarshal fail: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/oss/backend.go","lineNumber":676,"sourceCode":"\t\terr = fmt.Errorf(\"get Ecs sts token err : %s\", err.Error())\n\t\treturn\n\t}\n\n\tresponse := responses.NewCommonResponse()\n\terr = responses.Unmarshal(response, httpResponse, \"\")\n\tif err != nil {\n\t\terr = fmt.Errorf(\"unmarshal Ecs sts token response err : %s\", err.Error())\n\t\treturn\n\t}\n\n\tif response.GetHttpStatus() != http.StatusOK {\n\t\terr = fmt.Errorf(\"get Ecs sts token err, httpStatus: %d, message = %s\", response.GetHttpStatus(), response.GetHttpContentString())\n\t\treturn\n\t}\n\tvar data interface{}\n\terr = json.Unmarshal(response.GetHttpContentBytes(), &data)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"refresh Ecs sts token err, json.Unmarshal fail: %s\", err.Error())\n\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 {","sourceCodeStart":658,"sourceCodeEnd":694,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/oss/backend.go#L658-L694","documentation":"Returned by getAuthCredentialByEcsRoleName when json.Unmarshal of the metadata response body into interface{} fails. The metadata service returned a 200 but the body is not valid JSON, so the credential payload cannot be parsed.","triggerScenarios":"The metadata service returns HTML/text (e.g. an error page from an intercepting proxy), an empty body, or truncated JSON. Because the status check (error 335) passed first, this is specifically a content-vs-status mismatch.","commonSituations":"A captive/transparent proxy returning an HTML block page with a 200 status; metadata service returning a plain-text error string; SDK/transport truncating the body.","solutions":["curl the metadata URL directly and confirm the body is JSON like {\"AccessKeyId\":...,\"AccessKeySecret\":...,\"SecurityToken\":...,\"Code\":\"Success\"}.","Disable any HTTP proxy for 100.100.100.200 (set NO_PROXY to include it).","Retry for transient truncation; if persistent, fall back to static/STS credentials.","Ensure ecs_role_name is attached and returns proper JSON (see error 335)."],"exampleFix":"# before: corp proxy returns HTML 200 for metadata\nHTTP_PROXY=http://corp-proxy:8080\n\n# after: bypass proxy for metadata host\nNO_PROXY=100.100.100.200\nHTTP_PROXY=http://corp-proxy:8080","handlingStrategy":"validation","validationCode":"func metadataIsJSON(role string) error {\n    u := \"http://100.100.100.200/latest/meta-data/ram/security-credentials/\" + role\n    resp, err := http.Get(u)\n    if err != nil { return err }\n    defer resp.Body.Close()\n    b, _ := io.ReadAll(resp.Body)\n    var tmp interface{}\n    if err := json.Unmarshal(b, &tmp); err != nil {\n        return fmt.Errorf(\"metadata body is not JSON: %s\", string(b))\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := getAuthCredentialByEcsRoleName(role); err != nil {\n    if strings.Contains(err.Error(), \"json.Unmarshal fail\") {\n        // likely a proxy injecting HTML; retry without proxy\n        return getAuthCredentialByEcsRoleName(role)\n    }\n    return err\n}","preventionTips":["Add 100.100.100.200 to NO_PROXY.","curl the metadata URL to confirm JSON output.","Fall back to static creds when metadata is unreliable."],"tags":["oss","ecs","metadata","auth","json","network","backend"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}