SonarSource/sonarqube · error · BadRequestException

Project with key ' ' cannot be bound - configuration…

Error message

Project with key '{}' cannot be bound - configuration mismatch

What it means

ProjectCreator.getOrCreateProject() implements idempotent project creation/binding. When a project already exists with the given key but its stored name differs from the name in the request, it throws this BadRequestException. The detailed mismatch is logged internally, but the thrown message is deliberately vague to prevent information disclosure.

Solutions

  1. Align the projectName in the request with the existing project's actual name (GET api/projects/show?key=... to check).
  2. Rename the project (api/projects/update_name) to match your provisioning source of truth.
  3. Update the pipeline/provisioning config with the new name after a manual rename.
  4. Normalize name casing/whitespace in your provisioning templates before sending.

Example fix

// before
{name: 'Old App Name', key: 'com.example.app'} // stored name is 'My App'
// after
{name: 'My App', key: 'com.example.app'} // matches existing project
Defensive patterns

Strategy: validation

Validate before calling

// before create-or-bind, fetch the existing project and compare names
ProjectDto existing = dbClient.componentDao().selectByKey(db, requestKey).orElse(null);
if (existing != null && !existing.getName().equals(requestedName)) {
  throw new IllegalStateException("Name mismatch: stored='" + existing.getName() + "' requested='" + requestedName + "'");
}

Type guard

boolean nameMatches(ComponentDto project, String requestedName) {
  return project != null && project.getName().equals(requestedName);
}

Try / catch

catch (BadRequestException e) {
  // message is intentionally vague; fetch the real name via api/projects/show
  String actual = wsClient.get("api/projects/show?key=" + key)...name;
  throw new IllegalStateException("Fix provisioning name: stored='" + actual + "'");
}

Prevention

When it happens

Trigger: Calling the create-or-bind API (e.g. provisioning / api/projects/create used in binding flows) with a projectKey that exists but a projectName different from the stored one.

Common situations: Provisioning-as-code where the project was renamed in SonarQube but the pipeline config still has the old name; case/whitespace differences in the name; two systems disagreeing on the canonical project name.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/1920a91e14684d88. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-webserver-common/src/main/java/org/sonar/server/common/project/ProjectCreator.java:105

    
    if (existingProject.isPresent()) {
      if (!request.allowExisting()) {
        throw BadRequestException.create("Could not create Project with key: \"" + request.projectKey() + "\". A similar key already exists: \"" + request.projectKey() + "\"");
      }

      ProjectDto project = existingProject.get();

      // Require project administration to rebind an existing project. This check must happen before the name
      // comparison below so that an unauthorized caller cannot use the name-mismatch error as an oracle to
      // discover the real project name.
      userSession.checkEntityPermissionOrElseThrowResourceForbiddenException(ADMIN, project);

      // Validate name matches
      if (!project.getName().equals(request.projectName())) {
        // Log detailed info for debugging/auditing
        LOG.warn("Project binding failed: key '{}' exists with name '{}', expected '{}'",
            request.projectKey(), project.getName(), request.projectName());
        // Return vague error to prevent information disclosure
        throw BadRequestException.create("Project with key '" + request.projectKey() + "' cannot be bound - configuration mismatch");
      }

      // Return existing project data (not created)
      ComponentDto componentDto = dbClient.componentDao().selectByKey(dbSession, request.projectKey())
        .orElseThrow(() -> new IllegalStateException("Component not found for existing project"));
      BranchDto mainBranch = dbClient.branchDao().selectMainBranchByProjectUuid(dbSession, project.getUuid())
        .orElseThrow(() -> new IllegalStateException("Main branch not found"));

      return new ComponentCreationData(componentDto, null, mainBranch, project, false);
    }
    
    // Create new project
    ComponentCreationData creationData = createProject(dbSession, request.projectKey(), request.projectName(), request.mainBranchName(), 
        request.creationMethod(), request.isPrivate(), request.isManaged());
    
    // Explicitly mark as newly created
    return new ComponentCreationData(creationData.mainBranchComponent(), creationData.portfolioDto(), 

View on GitHub (pinned to 184c821202)