hashicorp/terraform · error

workspace %s not found For security, %s returns '404 Not Fo

Error message

workspace %s not found

For security, %s returns '404 Not Found' responses for resources
for resources that a user doesn't have access to, in addition to resources that
do not exist. If the resource does exist, please check the permissions of the provided token.

What it means

fetchWorkspace (backend.go:1336-1342) returns this when the go-tfe Workspaces.Read call fails with tfe.ErrResourceNotFound. The verbose message exists because HCP/TFE deliberately returns 404 both for non-existent resources and for resources the token lacks permission to see, so the error must disambiguate. This is the single most common workspace-access failure in the cloud backend.

Source

Thrown at internal/cloud/backend.go:1336

	hostname         string
	organization     string
	token            string
	workspaceMapping WorkspaceMapping
}

func isLocalExecutionMode(execMode string) bool {
	return execMode == "local"
}

func (b *Cloud) fetchWorkspace(ctx context.Context, organization string, workspace string) (*tfe.Workspace, error) {
	// Retrieve the workspace for this operation.
	w, err := b.client.Workspaces.Read(ctx, organization, workspace)
	if err != nil {
		switch err {
		case context.Canceled:
			return nil, err
		case tfe.ErrResourceNotFound:
			return nil, fmt.Errorf(
				"workspace %s not found\n\n"+
					fmt.Sprintf("For security, %s returns '404 Not Found' responses for resources\n", b.appName)+
					"for resources that a user doesn't have access to, in addition to resources that\n"+
					"do not exist. If the resource does exist, please check the permissions of the provided token.",
				workspace,
			)
		default:
			err := fmt.Errorf(
				"%s returned an unexpected error:\n\n%s",
				b.appName,
				err,
			)
			return nil, err
		}
	}

	return w, nil
}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Verify the workspace name and organization in your cloud block / TF_WORKSPACE / TF_CLOUD_ORGANIZATION are spelled exactly as in the HCP/TFE UI.
  2. Confirm the API token (TF_TOKEN_*, or `terraform login`) belongs to a team with at least Read access to that workspace.
  3. Check the workspace wasn't renamed, deleted, or moved to another project/org.
  4. For tag-based mapping, ensure at least one workspace actually carries the configured tags.

Example fix

// before
cloud { organization = "myorg" workspaces { name = "app-prod" } }
// -> workspace app-prod not found ...
// after: correct name (note dash vs underscore)
cloud { organization = "myorg" workspaces { name = "app_prod" } }
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: confirm the workspace is readable with the current token.
func workspaceExists(ctx context.Context, c *tfe.Client, org, ws string) bool {
    _, err := c.Workspaces.Read(ctx, org, ws)
    return err == nil
}

Try / catch

// Distinguish 404 from real-not-found vs permissions.
if errors.Is(err, tfe.ErrResourceNotFound) {
    // could be wrong name OR missing access; verify token team membership
}

Prevention

When it happens

Trigger: b.client.Workspaces.Read(ctx, organization, workspace) at backend.go:1330 returns an error that wraps/satisfies tfe.ErrResourceNotFound. Triggered by a wrong workspace name, wrong organization, or a token whose team has no access to that workspace.

Common situations: Typo in cloud block 'workspaces.name' or 'workspaces.tags' resolving to nothing. TF_WORKSPACE env var pointing at a non-existent workspace. Using an organization-scoped token in the wrong org. Token from a team that lacks 'Read' on the workspace. Recently renamed/deleted workspace.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/99081519cd6f10f6. Report an issue: GitHub.