{"record":{"id":"15a8de35ebbf8433","repo":"opentofu/opentofu","slug":"couldn-t-read-unredacted-json-plan-data-for-cloud","errorCode":null,"errorMessage":"couldn't read unredacted JSON plan data for cloud run %s; make sure you've run `tofu login` and that you have admin permissions on the workspace","messagePattern":"couldn't read unredacted JSON plan data for cloud run (.+?); make sure you've run `tofu login` and that you have admin permissions on the workspace","errorType":"exception","errorClass":null,"httpStatus":404,"severity":"error","filePath":"internal/cloud/backend_show.go","lineNumber":74,"sourceCode":"\t\t\topts = append(opts, plans.NoChanges)\n\t\t}\n\tdefault:\n\t\t// Bail, we can't use this.\n\t\terr = fmt.Errorf(\"can't display a cloud plan that is currently %s\", r.Plan.Status)\n\t\treturn nil, err\n\t}\n\n\t// Fetch the json plan!\n\tif redacted {\n\t\tjsonBytes, err = readRedactedPlan(ctx, b.client.BaseURL(), b.token, r.Plan.ID)\n\t} else {\n\t\tjsonBytes, err = b.client.Plans.ReadJSONOutput(ctx, r.Plan.ID)\n\t}\n\tif err == tfe.ErrResourceNotFound {\n\t\tif redacted {\n\t\t\treturn nil, fmt.Errorf(\"couldn't read plan data for cloud run %s; make sure you've run `tofu login` and that you have permission to view the run\", runID)\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"couldn't read unredacted JSON plan data for cloud run %s; make sure you've run `tofu login` and that you have admin permissions on the workspace\", runID)\n\t\t}\n\t} else if err != nil {\n\t\treturn nil, fmt.Errorf(\"couldn't read plan data for cloud run %s: %w\", runID, err)\n\t}\n\n\t// Format a run header and footer\n\theader := strings.TrimSpace(fmt.Sprintf(runHeader, b.hostname, b.organization, r.Workspace.Name, r.ID))\n\tfooter := strings.TrimSpace(statusFooter(r.Status, r.Actions.IsConfirmable, r.Workspace.Locked))\n\n\tout := &cloudplan.RemotePlanJSON{\n\t\tJSONBytes: jsonBytes,\n\t\tRedacted:  redacted,\n\t\tMode:      mode,\n\t\tQualities: opts,\n\t\tRunHeader: header,\n\t\tRunFooter: footer,\n\t}\n","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/cloud/backend_show.go#L56-L92","documentation":"Cloud.ShowPlanForRun got 404 when fetching the unredacted plan JSON via client.Plans.ReadJSONOutput. Unredacted plan output contains secret values (sensitive attribute values in full), so TFC/TFE only serves it to workspace-level admin tokens; a 404 here means no access or gone, and the message calls out the admin requirement.","triggerScenarios":"Showing a saved cloud plan through the unredacted path (e.g., `tofu show -json` where the caller requested unredacted output) with a token that is not a workspace admin, or credentials missing/expired, or the plan no longer existing.","commonSituations":"CI token with broad run permissions but not workspace admin; team-level tokens reading plans for audit; user whose admin role was revoked after the plan was saved.","solutions":["Use a token whose identity has admin permission on that workspace (organization owners, or a team granted workspace admin), then retry","If you do not need secret values, show the redacted variant instead (default `tofu show` behavior redacts sensitive values)","Verify you are logged in to the correct hostname/org via `tofu login`","If permissions are right but the plan is old, the run may have been purged — create a new plan"],"exampleFix":"# before: team token without workspace admin\n$ tofu show -json plan.tfplan\n# Error: couldn't read unredacted JSON plan data for cloud run run-XXXX...\n\n# after: use an org-owner token for this host\n$ export TF_TOKEN_app_terraform_io=<admin-token>\n$ tofu show -json plan.tfplan","handlingStrategy":"validation","validationCode":"// Unredacted output needs workspace admin: check the identity first.\nperms, _ := client.Workspaces.ReadPermissions(ctx, wsID) // conceptual permission read\nif !workspaceAdmin(perms) {\n    fmt.Fprintln(os.Stderr, \"falling back to redacted plan output\")\n    redacted = true\n}","typeGuard":"func canReadUnredacted(wsPerms *tfe.WorkspacePermissions) bool {\n\treturn wsPerms != nil && wsPerms.Admin // conceptual: gate on workspace admin\n}","tryCatchPattern":"b, err := client.Plans.ReadJSONOutput(ctx, planID)\nif errors.Is(err, tfe.ErrResourceNotFound) && !redacted {\n    // retry once with redacted output rather than failing the pipeline\n    b, err = readRedactedPlan(ctx, baseURL, token, planID)\n}","preventionTips":["Default automation to redacted plan output; request unredacted only when secrets are genuinely needed","Reserve unredacted access for break-glass admin tokens","Document which identities hold workspace admin per workspace"],"tags":["cloud-backend","plan-output","permissions","admin","sensitive-data"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}