hashicorp/terraform · error
error downloading state: %v
Error message
error downloading state: %v
What it means
After reading current-state-version metadata, Terraform downloads the actual state bytes from sv.DownloadURL via StateVersions.Download. This wraps any failure of that download: the (often expiring) download URL may be unreachable, expired, or the object-storage backend unavailable.
Source
Thrown at internal/cloud/state.go:422
func (s *State) getStatePayload() (*remote.Payload, error) {
ctx := context.Background()
// Check the x-terraform-snapshot-interval header to see if it has a non-empty
// value which would indicate snapshots are enabled
ctx = tfe.ContextWithResponseHeaderHook(ctx, s.readSnapshotIntervalHeader)
sv, err := s.tfeClient.StateVersions.ReadCurrent(ctx, s.workspace.ID)
if err != nil {
if err == tfe.ErrResourceNotFound {
// If no state exists, then return nil.
return nil, nil
}
return nil, fmt.Errorf("error retrieving state: %v", err)
}
state, err := s.tfeClient.StateVersions.Download(ctx, sv.DownloadURL)
if err != nil {
return nil, 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
}
type errorUnlockFailed struct {
innerError errorView on GitHub (pinned to c9def3e214)
Solutions
- Ensure network egress permits BOTH the HCP/TFE API host and the state storage host.
- Retry immediately; a fresh download URL is issued each time.
- Reduce state size (split workspaces) if downloads repeatedly time out.
- Check proxy/TLS-interception settings that may break the download.
Example fix
# before: egress firewall allows api host but blocks state storage host -> download fails # after: allow egress to the state storage hostname (e.g. S3 backend domain), then refresh terraform refresh
Defensive patterns
Strategy: retry
Try / catch
if err := state.RefreshState(); err != nil {
if isTransientHTTP(err) || isDownloadError(err) {
// bounded retry; a fresh DownloadURL is issued each ReadCurrent
}
} Prevention
- Allow egress to both the API host and the state-storage host
- Retry immediately on expired presigned URLs
- Keep state size manageable to avoid download timeouts
When it happens
Trigger: getStatePayload succeeds at ReadCurrent but StateVersions.Download(url) fails: network egress blocked to the state-storage host, the presigned URL expired, or the object-storage endpoint returned an error.
Common situations: Restrictive egress proxies that permit the TFE API hostname but block the state-storage hostname, a large state over a flaky link, or an expired presigned URL after a long delay.
Related errors
- listing blobs: %v
- listing Keys for %s: %+v
- querying Cloud Storage failed: %v
- error retrieving state: %v
- consul lock was lost
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/2e83cebad7c04037.
Report an issue: GitHub.