API-created projects ignore global default main branch setting (sonar.projectCreation.mainBranchName

Description:
We’ve noticed that when creating SonarQube projects via the REST API (/api/projects/create), the global default main branch setting (sonar.projectCreation.mainBranchName) is not applied.

Currently:

  • UI-created projects: Respect this setting.

  • API-created projects: Ignore this setting, defaulting to master.

  • DevOps platform imports: Also ignore this setting.

Impact:
This behavior causes inconsistency between UI-created and API-created projects. In environments where projects are provisioned automatically via CI/CD pipelines, the main branch defaults to master regardless of organizational conventions (e.g., main), and there is no API mechanism to override it.

This has several implications:

  • Teams must manually run a first analysis on the intended main branch to correct it.

  • Automated provisioning pipelines cannot enforce branch naming consistency.

  • Documentation may mislead users into expecting the global default to apply in API workflows.

Supporting Documentation:

“If you add your project manually, your main branch defaults to the name master.”

  • Observed behavior: Projects created via /api/projects/create ignore sonar.projectCreation.mainBranchName and default to master.

Requested Enhancement / Question:

  • Can the API provide an option to specify the main branch at project creation?

  • Alternatively, can the global default sonar.projectCreation.mainBranchName be applied to API-created projects, just like UI-created projects?

Environment / Version:

  • SonarQube Server Version: Developer Edition v2025.5

  • API: /api/projects/create

Additional Notes:
This limitation currently requires extra manual steps or first-analysis workarounds to ensure consistent main branch naming across automated projects.

Hi,

Can you give your context for this? I.e. what SonarQube flavor and version are you on?

 
Thx,
Ann

Hi Ann,

Thanks for the quick response.

Here’s my context:

SonarQube Edition: Developer Edition
Version: v2025.5 (113872)
Experience: Standard Experience (ACTIVE)

I have configured the global setting:

sonar.projectCreation.mainBranchName = main

This works as expected when projects are created via the UI.

However, when creating a project via the REST API, the project is always created with master as the main branch, ignoring the global default.

This is the API call I’m using:

url=${SONARQUBE_URL}
url_createSonarProject="${url}/api/projects/create"

curl -s -u "${sonar_token}" -k -X POST \
  -d "name=${SONARQUBE_PROJECT}&project=${SONARQUBE_PROJECT_KEY}&visibility=private" \
  "${url_createSonarProject}"

As a workaround, I found that I can rename the main branch afterward using the API, for example:

url=${SONARQUBE_URL}
url_renameDefaultBranch="${url}/api/project_branches/rename"

curl -s -u "${sonar_token}" -k -X POST \
  -d "project=${SONARQUBE_PROJECT_KEY}&name=${default_branch}" \
  "${url_renameDefaultBranch}"

That said, this still requires an extra step in automated provisioning pipelines. Ideally, the global sonar.projectCreation.mainBranchName setting would also apply to API-created projects, or the /api/projects/create endpoint would allow explicitly specifying the main branch.

Hi,

Thanks for the detail.

I completely agree. I’m going to flag this for the team.

 
Ann

Hi @Claudia_Tavares ,

Thank you for the detailed report, the context is very helpful.

Immediate workaround: The /api/projects/create endpoint supports an explicit mainBranch parameter since v9.8, so you can include it directly in your API call without needing the extra rename step:

curl -s -u "${sonar_token}:" -k -X POST \
  -d "name=${SONARQUBE_PROJECT}&project=${SONARQUBE_PROJECT_KEY}&visibility=private&mainBranch=main" \
  "${url_createSonarProject}"

Regarding the global setting behavior: From what I can tell, the server-side code for /api/projects/create does fall back to the sonar.projectCreation.mainBranchName global setting when the mainBranch parameter is not provided. This is the same code path used when creating projects via the UI, the difference is that the UI reads the setting and sends it explicitly in the request, whereas the API relies on the server-side fallback.

To help us investigate why you’re seeing master instead of main, could you run the following API call and share the output?

curl --request GET \
  --url '${SONARQUBE_URL}/api/settings/values?keys=sonar.projectCreation.mainBranchName' \
  --header 'authorization: Bearer <sonar_token>'

This will confirm whether the setting is properly stored and accessible to the server.

Please let us know what that returns, and we can dig further from there.

Best,
Robert

Hi Robert,

Thank you for the clarification.

I wasn’t aware that mainBranch could be passed directly as a parameter to /api/projects/create, but including it in the request resolves the issue on our side. That’s definitely a cleaner approach than the rename step — thanks for pointing that out.

Regarding the second API call, here is the response we get:

{"settings":[{"key":"sonar.projectCreation.mainBranchName","value":"main","inherited":true}],"setSecuredSettings":[]}

So the global setting is correctly configured to main.

Thanks again for your help!