{"record":{"id":"e5ea6b06301fea2b","repo":"hashicorp/terraform","slug":"error-downloading-state-v","errorCode":null,"errorMessage":"Error downloading state: %v","messagePattern":"Error downloading state: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote/backend_state.go","lineNumber":67,"sourceCode":"var _ Fatal = errorUnlockFailed{}\n\n// Get the remote state.\nfunc (r *remoteClient) Get() (*remote.Payload, tfdiags.Diagnostics) {\n\tvar diags tfdiags.Diagnostics\n\tctx := context.Background()\n\n\tsv, err := r.client.StateVersions.ReadCurrent(ctx, r.workspace.ID)\n\tif err != nil {\n\t\tif err == tfe.ErrResourceNotFound {\n\t\t\t// If no state exists, then return nil.\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn nil, diags.Append(fmt.Errorf(\"Error retrieving state: %v\", err))\n\t}\n\n\tstate, err := r.client.StateVersions.Download(ctx, sv.DownloadURL)\n\tif err != nil {\n\t\treturn nil, diags.Append(fmt.Errorf(\"Error downloading state: %v\", err))\n\t}\n\n\t// If the state is empty, then return nil.\n\tif len(state) == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Get the MD5 checksum of the state.\n\tsum := md5.Sum(state)\n\n\treturn &remote.Payload{\n\t\tData: state,\n\t\tMD5:  sum[:],\n\t}, nil\n}\n\nfunc (r *remoteClient) uploadStateFallback(ctx context.Context, stateFile *statefile.File, state []byte, jsonStateOutputs []byte) error {\n\toptions := tfe.StateVersionCreateOptions{","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote/backend_state.go#L49-L85","documentation":"After ReadCurrent returns the state version metadata, the backend downloads the actual state bytes from sv.DownloadURL — a short-lived presigned URL pointing at TFC's object-storage backend (typically S3 for TFC, configurable storage for TFE). A failure here is almost always at the storage/transport layer, not the TFC API.","triggerScenarios":"StateVersions.Download(ctx, sv.DownloadURL) fails: the presigned URL expired before the request fired, the object-storage endpoint is unreachable, the TLS connection to S3 (or TFE's configured external store) is blocked, the state object was deleted out-of-band, or the response failed checksum/streaming.","commonSituations":"Long latency between ReadCurrent and Download (URL TTL exceeded); corporate egress proxy blocking the S3 domain; TFE misconfigured object storage; large state timing out; clock skew invalidating the presigned URL signature.","solutions":["Retry immediately — presigned-URL and transient S3 errors usually clear on the next attempt.","Ensure egress to TFC's state storage endpoints (e.g. *.s3.amazonaws.com for TFC) is allowed by your proxy/firewall.","For TFE, verify the object-storage backend configuration and credentials are healthy.","Check for clock skew on the client (NTP) which can break presigned-URL signatures."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Download within the presigned-URL TTL — call immediately after ReadCurrent\nstate, err := c.StateVersions.Download(ctx, sv.DownloadURL)\nif err != nil { return err }","typeGuard":null,"tryCatchPattern":"// Retry S3/storage hiccups with backoff; re-ReadCurrent to refresh URL if expired\nerr := retry.Backoff(5, func() error {\n    fresh, e := c.StateVersions.ReadCurrent(ctx, wsID); if e != nil { return e }\n    _, e = c.StateVersions.Download(ctx, fresh.DownloadURL)\n    return e\n})","preventionTips":["Keep latency between ReadCurrent and Download minimal to stay inside the URL TTL.","Whitelist TFC/TFE state-storage egress (*.s3.amazonaws.com or your TFE store) on proxies.","Sync client clock via NTP to avoid presigned-URL signature failures."],"tags":["terraform","remote-backend","tfe","state","object-storage","network","presigned-url"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}