{"record":{"id":"1d586be51b1c9e85","repo":"hashicorp/terraform","slug":"s-returned-an-unexpected-error-s","errorCode":null,"errorMessage":"%s returned an unexpected error:\n\n%s","messagePattern":"(.+?) returned an unexpected error:\n\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloud/backend.go","lineNumber":1344,"sourceCode":"}\n\nfunc (b *Cloud) fetchWorkspace(ctx context.Context, organization string, workspace string) (*tfe.Workspace, error) {\n\t// Retrieve the workspace for this operation.\n\tw, err := b.client.Workspaces.Read(ctx, organization, workspace)\n\tif err != nil {\n\t\tswitch err {\n\t\tcase context.Canceled:\n\t\t\treturn nil, err\n\t\tcase tfe.ErrResourceNotFound:\n\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\"workspace %s not found\\n\\n\"+\n\t\t\t\t\tfmt.Sprintf(\"For security, %s returns '404 Not Found' responses for resources\\n\", b.appName)+\n\t\t\t\t\t\"for resources that a user doesn't have access to, in addition to resources that\\n\"+\n\t\t\t\t\t\"do not exist. If the resource does exist, please check the permissions of the provided token.\",\n\t\t\t\tworkspace,\n\t\t\t)\n\t\tdefault:\n\t\t\terr := fmt.Errorf(\n\t\t\t\t\"%s returned an unexpected error:\\n\\n%s\",\n\t\t\t\tb.appName,\n\t\t\t\terr,\n\t\t\t)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn w, nil\n}\n\n// validWorkspaceEnvVar ensures we have selected a valid workspace using TF_WORKSPACE:\n// First, it ensures the workspace specified by TF_WORKSPACE exists in the organization.\n// (This is because we deliberately DON'T implicitly create a workspace from TF_WORKSPACE,\n// unlike with a workspace specified via `name`.)\n// Second, if tags are specified in the configuration, it ensures TF_WORKSPACE belongs to the set\n// of available workspaces with those given tags.\nfunc (b *Cloud) validWorkspaceEnvVar(ctx context.Context, organization, workspace string) tfdiags.Diagnostic {","sourceCodeStart":1326,"sourceCodeEnd":1362,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/cloud/backend.go#L1326-L1362","documentation":"fetchWorkspace's default branch: Workspaces.Read returned an error that is neither context.Canceled nor tfe.ErrResourceNotFound. The backend wraps and rethrows so callers see which host produced what. This is the catch-all for transport, auth, rate-limit, and server errors.","triggerScenarios":"Workspaces.Read returns non-canceled, non-404: 401 unauthorized (bad/expired token); 429 rate limit; 500/502/503 from TFE; DNS/TLS failure to the configured hostname; malformed response deserialization in the TFE client.","commonSituations":"Expired API token; TFE instance behind a flaky load balancer; hitting rate limits during a large matrix CI run; self-hosted TFE cert renewed with a chain the runner does not trust.","solutions":["Inspect the wrapped error for an HTTP status—refresh the token on 401, back off on 429.","Verify network/TLS connectivity to the configured hostname from the runner.","Retry transient 5xx with exponential backoff at the workflow level.","Confirm the TFE client version bundled with the binary matches the server's API surface."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"func reachable(client *tfe.Client) error {\n    // ping the org to detect auth/transport issues early\n    if _, err := client.Organizations.Read(ctx, org); err != nil {\n        return fmt.Errorf(\"TFE unreachable or unauthorized: %w\", err)\n    }\n    return nil\n}","typeGuard":"func isRetryableTFE(err error) bool {\n    var apiErr *tfeerror.Error\n    if errors.As(err, &apiErr) {\n        switch apiErr.Status {\n        case 429, 500, 502, 503, 504:\n            return true\n        }\n    }\n    return errors.Is(err, context.DeadlineExceeded) || isTransientNet(err)\n}","tryCatchPattern":"backoff.Retry(func() error {\n    ws, err := client.Workspaces.Read(ctx, org, name)\n    if isRetryableTFE(err) { return err }\n    if err != nil { return backoff.Permanent(err) }\n    _ = ws\n    return nil\n}, backoff.NewExponentialBackOff())","preventionTips":["Refresh long-lived tokens or use short-lived dynamic credentials.","Verify TLS/DNS to the TFE hostname from the runner.","Retry 429/5xx with exponential backoff.","Keep the tfe client SDK close to the server version."],"tags":["tfe","hcp","cloud-backend","workspace","network","auth"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}