hashicorp/terraform · error
error creating workspace
Error message
error creating workspace %s: %v
What it means
Returned when b.client.Workspaces.Create fails for the resolved workspace name. This is the terminal step of the create-workspace path: project (if any) was resolved above, then the workspace POST itself errored. The wrapped %v is the raw TFE client error, so HTTP status and API message travel with it.
Solutions
- Verify the workspace name matches TFE naming rules (lowercase alphanumerics, _, -, max 90 chars) and rerun.
- Confirm the API token has 'Workspaces: Admin' / create scope on the target organization.
- Check the organization spelling in the cloud block and the hostname in `hostname`.
- If the workspace already exists, do not rely on auto-create—reference it explicitly and ensure the token can read it.
- For races, serialize `init` across CI agents or pre-create the workspace.
Example fix
// before
cloud {
organization = "acme"
workspaces { name = "Prod Env" }
}
// after
cloud {
organization = "acme"
workspaces { name = "prod-env" }
} Defensive patterns
Strategy: validation
Validate before calling
func validWorkspaceName(name string) error {
if name == "" || len(name) > 90 {
return fmt.Errorf("workspace name length invalid")
}
if !regexp.MustCompile(`^[a-z0-9][a-z0-9_-]*$`).MatchString(name) {
return fmt.Errorf("workspace name %q must be lowercase alnum/-/_", name)
}
return nil
}
// also confirm token scope:
// Workspaces: Admin on the target organization Prevention
- Verify workspace name conforms to TFE rules before init.
- Ensure the token has workspace-create scope on the org.
- If the workspace exists, reference it rather than relying on auto-create.
- Serialize concurrent inits against a new workspace name.
When it happens
Trigger: Workspaces.Create(ctx, org, workspaceCreateOptions) returns non-nil err: 409 workspace name already exists in the org; 422 for invalid name or duplicate-when-not-allowed; 401/403 if the token cannot create workspaces; 404 if the organization itself is wrong; transport/timeout against the TFE host.
Common situations: TF_WORKSPACE points at a name with uppercase letters or spaces; the cloud block's `name` collides with an existing workspace the token can read but not write; the organization string is misspelled so the org lookup 404s into a create failure; an auto-create race between two `terraform init` runs.
Related errors
- workspace not found For security, returns '404 Not Found'…
- error finding remote workspace
- error updating workspace
- failed to create project
- returned an unexpected error
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/64a7c2ef8b3d2189.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cloud/backend.go:810
createOpts := tfe.ProjectCreateOptions{
Name: b.WorkspaceMapping.Project,
}
// didn't find project, create it instead
log.Printf("[TRACE] cloud: Creating %s project %s/%s", b.appName, b.Organization, b.WorkspaceMapping.Project)
project, err := b.client.Projects.Create(context.Background(), b.Organization, createOpts)
if err != nil && err != tfe.ErrResourceNotFound {
return nil, diags.Append(fmt.Errorf("failed to create project %s: %v", b.WorkspaceMapping.Project, err))
}
configuredProject = project
workspaceCreateOptions.Project = configuredProject
}
}
// Create a workspace
log.Printf("[TRACE] cloud: Creating %s workspace %s/%s", b.appName, b.Organization, name)
workspace, err = b.client.Workspaces.Create(context.Background(), b.Organization, workspaceCreateOptions)
if err != nil {
return nil, diags.Append(fmt.Errorf("error creating workspace %s: %v", name, err))
}
remoteTFVersion = workspace.TerraformVersion
// Attempt to set the new workspace to use this version of Terraform. This
// can fail if there's no enabled tool_version whose name matches our
// version string, but that's expected sometimes -- just warn and continue.
versionOptions := tfe.WorkspaceUpdateOptions{
TerraformVersion: tfe.String(tfversion.String()),
}
_, err := b.client.Workspaces.UpdateByID(context.Background(), workspace.ID, versionOptions)
if err == nil {
remoteTFVersion = tfversion.String()
} else {
// TODO: Ideally we could rely on the client to tell us what the actual
// problem was, but we currently can't get enough context from the error
// object to do a nicely formatted message, so we're just assuming the
// issue was that the version wasn't available since that's probably whatView on GitHub (pinned to d32a084675)