hashicorp/terraform · error
Error downloading state
Error message
Error downloading state: %v
What it means
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.
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.
Defensive patterns
Strategy: retry
Validate before calling
// Download within the presigned-URL TTL — call immediately after ReadCurrent
state, err := c.StateVersions.Download(ctx, sv.DownloadURL)
if err != nil { return err } Try / catch
// Retry S3/storage hiccups with backoff; re-ReadCurrent to refresh URL if expired
err := retry.Backoff(5, func() error {
fresh, e := c.StateVersions.ReadCurrent(ctx, wsID); if e != nil { return e }
_, e = c.StateVersions.Download(ctx, fresh.DownloadURL)
return e
}) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Error retrieving state
- error downloading state
- error loading workspace
- failed checking for existing remote state
- lock ID does not match existing lock
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/e5ea6b06301fea2b.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote/backend_state.go:67
var _ Fatal = errorUnlockFailed{}
// Get the remote state.
func (r *remoteClient) Get() (*remote.Payload, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
ctx := context.Background()
sv, err := r.client.StateVersions.ReadCurrent(ctx, r.workspace.ID)
if err != nil {
if err == tfe.ErrResourceNotFound {
// If no state exists, then return nil.
return nil, nil
}
return nil, diags.Append(fmt.Errorf("Error retrieving state: %v", err))
}
state, err := r.client.StateVersions.Download(ctx, sv.DownloadURL)
if err != nil {
return nil, diags.Append(fmt.Errorf("Error downloading state: %v", err))
}
// If the state is empty, then return nil.
if len(state) == 0 {
return nil, nil
}
// Get the MD5 checksum of the state.
sum := md5.Sum(state)
return &remote.Payload{
Data: state,
MD5: sum[:],
}, nil
}
func (r *remoteClient) uploadStateFallback(ctx context.Context, stateFile *statefile.File, state []byte, jsonStateOutputs []byte) error {
options := tfe.StateVersionCreateOptions{View on GitHub (pinned to d32a084675)