hashicorp/terraform · error
couldn't read plan data for cloud run %s: %w
Error message
couldn't read plan data for cloud run %s: %w
What it means
Returned by ShowPlanForRun when fetching plan JSON (redacted or unredacted) fails with an error other than tfe.ErrResourceNotFound. The underlying cause is wrapped for diagnostics.
Source
Thrown at internal/cloud/backend_show.go:75
// Bail, we can't use this.
err = fmt.Errorf("can't display a cloud plan that is currently %s", r.Plan.Status)
return nil, err
}
// Fetch the json plan!
if redacted {
jsonBytes, err = readRedactedPlan(ctx, b.client.BaseURL(), b.Token, r.Plan.ID)
} else {
jsonBytes, err = b.client.Plans.ReadJSONOutput(ctx, r.Plan.ID)
}
if err == tfe.ErrResourceNotFound {
if redacted {
return nil, fmt.Errorf("couldn't read plan data for cloud run %s; make sure you've run `terraform login` and that you have permission to view the run", runID)
} else {
return nil, fmt.Errorf("couldn't read unredacted JSON plan data for cloud run %s; make sure you've run `terraform login` and that you have admin permissions on the workspace", runID)
}
} else if err != nil {
return nil, fmt.Errorf("couldn't read plan data for cloud run %s: %w", runID, err)
}
// Format a run header and footer
header := strings.TrimSpace(fmt.Sprintf(runHeader, b.Hostname, b.Organization, r.Workspace.Name, r.ID))
footer := strings.TrimSpace(statusFooter(r.Status, r.Actions.IsConfirmable, r.Workspace.Locked))
out := &cloudplan.RemotePlanJSON{
JSONBytes: jsonBytes,
Redacted: redacted,
Mode: mode,
Qualities: opts,
RunHeader: header,
RunFooter: footer,
}
return out, nil
}
View on GitHub (pinned to c9def3e214)
Solutions
- Inspect the wrapped %w cause to classify (network vs auth vs server).
- Retry with backoff for transient (5xx, timeout) errors.
- Re-authenticate if the cause is an auth/permission error (401/403 surfaced as non-404).
- Check HCP/TFE status and plan-output endpoint health.
Example fix
// before
b, err := b.client.Plans.ReadJSONOutput(ctx, planID)
// after: classify and retry transient, surface persistent
if err != nil && !errors.Is(err, tfe.ErrResourceNotFound) {
if isTransient(err) { return retry() }
return fmt.Errorf("couldn't read plan data for cloud run %s: %w", runID, err)
} Defensive patterns
Strategy: retry
Type guard
func isTransientPlanReadErr(err error) bool {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() { return true }
s := err.Error()
return strings.Contains(s, "context deadline") || strings.Contains(s, "503") || strings.Contains(s, "502")
} Try / catch
backoff := time.Second
for i := 0; i < 3; i++ {
jsonBytes, err = read(b, ctx, r.Plan.ID)
if err == nil { break }
if errors.Is(err, tfe.ErrResourceNotFound) || !isTransientPlanReadErr(err) { break }
time.Sleep(backoff); backoff *= 2
} Prevention
- Retry transient plan-output reads with backoff.
- Keep context deadlines generous for streamed JSON.
- Re-authenticate on persistent auth-class errors.
When it happens
Trigger: readRedactedPlan or Plans.ReadJSONOutput returns a non-404 failure: 5xx, timeout, context cancellation, streaming/JSON decode error, auth token rejected mid-request.
Common situations: Transient API outage, network interruption during the streamed plan JSON read, expired token, or a malformed plan JSON object on the server.
Related errors
- couldn't read information for cloud run %s: %w
- operation timed out
- a network issue prevented cloud configuration; %w
- %s returned an unexpected error: %s
- hostname for run (%s) does not match the configured cloud in
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/e156a47f82a31786.
Report an issue: GitHub.