bitwarden/server · warning · BadRequestException

The maximum number of projects for this plan is ({max}).

Error message

The maximum number of projects for this plan is ({max}).

What it means

Thrown at SecretsManagerPortingController.cs:84 inside Import. When projectsToAdd > 0, the IMaxProjectsQuery.GetByOrgIdAsync returns (max, overMax); if overMax is true the request would push the organization past its plan's project cap, so the controller throws BadRequestException($"The maximum number of projects for this plan is ({max}).") -> HTTP 400 with the numeric limit interpolated. This is a plan/entitlement business limit, not malformed input.

Source

Thrown at src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs:84

        }

        if (importRequest.Projects?.Count() > 1000 || importRequest.Secrets?.Count() > 6000)
        {
            throw new BadRequestException("You cannot import this much data at once, the limit is 1000 projects and 6000 secrets.");
        }

        if (importRequest.Secrets.Any(s => s.ProjectIds.Count() > 1))
        {
            throw new BadRequestException("A secret can only be in one project at a time.");
        }

        var projectsToAdd = importRequest.Projects?.Count();
        if (projectsToAdd is > 0)
        {
            var (max, overMax) = await _maxProjectsQuery.GetByOrgIdAsync(organizationId, projectsToAdd.Value);
            if (overMax != null && overMax.Value)
            {
                throw new BadRequestException($"The maximum number of projects for this plan is ({max}).");
            }
        }

        await _importCommand.ImportAsync(organizationId, importRequest.ToSMImport());
    }
}

View on GitHub (pinned to e93b962371)

Solutions

  1. Upgrade the organization's plan to raise the project maximum, then re-import.
  2. Delete or consolidate existing projects to free quota before importing.
  3. Import only projects that fit under the remaining quota and defer the rest.

Example fix

// before: import would exceed plan cap
await adminClient.PostAsync($"/sm/{orgId}/import", importJson); // 400: max is (N)

// after: check remaining quota, then upgrade or trim
var remaining = await GetRemainingProjectQuotaAsync(orgId);
if (import.Projects.Count() > remaining) {
    await UpgradePlanAsync(orgId); // or trim the import set
}
await adminClient.PostAsync($"/sm/{orgId}/import", importJson);
Defensive patterns

Strategy: validation

Validate before calling

var (max, used) = await GetProjectQuotaAsync(orgId);
if (used + import.Projects.Count() > max)
    throw new InvalidOperationException($"Would exceed plan cap of {max} projects");

Prevention

When it happens

Trigger: POST /sm/{org}/import whose new project count, added to existing projects, exceeds the organization's current plan tier project maximum.

Common situations: Free/starter plan org trying to import a large project set; plan downgrade left the org at/over cap; bulk import after already using the quota.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/d64f17c41e409857. Report an issue: GitHub.