theonedev/onedev · error · NotAcceptableException

Name is already used by another SSO provider

Error message

Name is already used by another SSO provider

What it means

Before creating an SSO provider via REST, createSsoProvider checks ssoProviderService.find(ssoProvider.getName()); if an existing provider already uses the requested name, a NotAcceptableException (406) is thrown. Provider names are unique keys, so duplicates cannot be created.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/SsoProviderResource.java:80

	public Long getSsoProviderId(@PathParam("name") String name) {
    	if (!SecurityUtils.isAdministrator()) 
			throw new UnauthorizedException();

		var ssoProvider = ssoProviderService.find(name);
		if (ssoProvider != null)
			return ssoProvider.getId();
		else
			throw new NotFoundException();
	}

	@Api(order=300, description="Create SSO provider")
    @POST
    public Long createSsoProvider(@NotNull @Valid SsoProvider ssoProvider) {
    	if (!SecurityUtils.isAdministrator()) 
			throw new UnauthorizedException();

		if (ssoProviderService.find(ssoProvider.getName()) != null)
			throw new NotAcceptableException("Name is already used by another SSO provider");

		ssoProviderService.createOrUpdate(ssoProvider);
		var auditContent = VersionedXmlDoc.fromBean(ssoProvider).toXML();
		auditService.audit(null, "created SSO provider \"" + ssoProvider.getName() + "\" via RESTful API", null, auditContent);

    	return ssoProvider.getId();
    }

	@Api(order=350, description="Update SSO provider of specified id")
	@Path("/{ssoProviderId}")
	@POST
	public Response updateSsoProvider(@PathParam("ssoProviderId") Long ssoProviderId, @NotNull @Valid SsoProvider ssoProvider) {
		if (!SecurityUtils.isAdministrator())
			throw new UnauthorizedException();

		SsoProvider existingSsoProvider = ssoProviderService.find(ssoProvider.getName());
		if (existingSsoProvider != null && !existingSsoProvider.equals(ssoProvider))
			throw new NotAcceptableException("Name is already used by another SSO provider");

View on GitHub (pinned to d44925c47c)

Solutions

  1. Choose a unique name for the new SSO provider.
  2. List existing providers (GET the collection endpoint) and reuse/rename instead of creating a duplicate.
  3. Make automation idempotent: check for an existing provider first and update its id via the update endpoint instead of POSTing a new one.

Example fix

// before
POST /~api/sso-providers {"name":"azure-ad", ...}   // 406 if 'azure-ad' exists
// after: check first, then update
GET /~api/sso-providers -> find id of 'azure-ad'
POST /~api/sso-providers/{id} {"id":id, "name":"azure-ad", ...}
Defensive patterns

Strategy: validation

Validate before calling

const providers = await fetch('/~api/sso-providers', {headers: {Authorization: auth}}).then(r => r.json());
if (providers.some(p => p.name === newProvider.name))
  throw new Error(`SSO provider name '${newProvider.name}' already in use`);

Prevention

When it happens

Trigger: POST to the SSO provider collection endpoint with a JSON body whose 'name' field equals an existing provider's name (case-sensitive lookup by exact name).

Common situations: Re-running an idempotent provisioning script without a duplicate check; copying an exported provider config and posting it unchanged; re-creating a provider that was renamed rather than deleted.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/40e7a5bc80e21da1. Report an issue: GitHub.