theonedev/onedev · error · UnauthorizedException

Not authorized to create root project

Error message

Not authorized to create root project

What it means

OneDev throws this UnauthorizedException when a user attempts to create (or implicitly create via a nested path) a project at the repository root without having the 'Create Root Projects' permission. In DefaultProjectService.setup, when walking a project path, if no project with the given name exists and there is no parent project, the current Subject is checked with SecurityUtils.canCreateRootProjects; failing that check aborts the operation.

Source

Thrown at server-core/src/main/java/io/onedev/server/service/impl/DefaultProjectService.java:562

	@Override
	public Project setup(Subject subject, String path) {
		List<String> names = Splitter.on("/").omitEmptyStrings().trimResults().splitToList(path);
		Project project = null;
		for (String name : names) {
			Project child;
			if (project == null || !project.isNew()) {
				// Query database directly instead of calling findByName to fix issue 
				// #923 - Multi level projects after import and 1dev upgrade are mingled
				EntityCriteria<Project> criteria = EntityCriteria.of(Project.class);
				if (project != null)
					criteria.add(Restrictions.eq(Project.PROP_PARENT, project));
				else
					criteria.add(Restrictions.isNull(Project.PROP_PARENT));
				criteria.add(Restrictions.eq(Project.PROP_NAME, name));
				child = find(criteria);
				if (child == null) {
					if (project == null && !SecurityUtils.canCreateRootProjects(subject))
						throw new UnauthorizedException(_T("Not authorized to create root project"));
					if (project != null && !SecurityUtils.canCreateChildren(subject, project))
						throw new UnauthorizedException(MessageFormat.format(_T("Not authorized to create project under \"{0}\""), project.getPath()));
					child = new Project();
					child.setName(name);
					child.setParent(project);
				}
			} else {
				child = new Project();
				child.setName(name);
				child.setParent(project);
			}
			project = child;
		}

		Project parent = project.getParent();
		while (parent != null && parent.isNew()) {
			parent.setCodeManagement(false);
			parent.setIssueManagement(false);

View on GitHub (pinned to d44925c47c)

Solutions

  1. Grant the user (or their group) the 'Create Root Projects' permission in OneDev security settings, or make the user an administrator.
  2. Create the project under an existing parent project instead (path like parent/child), where 'Create Children' permission on the parent suffices.
  3. Have an administrator create the root project and grant the user access to it.
  4. If triggered by automation, use credentials of a service account that has the required permission.

Example fix

// before
curl -X POST -u regularuser:pass -H 'Content-Type: application/json' \
  -d '{"name":"myproject"}' https://onedev.example.com/api/projects
// after: create under a parent the user may write to
curl -X POST -u regularuser:pass -H 'Content-Type: application/json' \
  -d '{"name":"team-space/myproject"}' https://onedev.example.com/api/projects
Defensive patterns

Strategy: try-catch

Validate before calling

// REST client pre-check: confirm the path is not root, or the user can create root projects
var path = projectName.contains("/") ? projectName.substring(0, projectName.lastIndexOf('/')) : null;
if (path == null && !isRootProjectCreator(user)) {
    throw new IllegalStateException("User lacks 'Create Root Projects' permission");
}

Type guard

function canCreateRoot(user) {
  return typeof user === 'object' && user !== null &&
    Array.isArray(user.permissions) && user.permissions.includes('CREATE_ROOT_PROJECTS');
}

Try / catch

try {
    projectService.setup(subject, projectName);
} catch (UnauthorizedException e) {
    logger.warn("Project creation not permitted: {}", e.getMessage());
    // surface a permission request to the user or fall back to a permitted parent
}

Prevention

When it happens

Trigger: Calling ProjectService.setup (e.g. via REST API POST /api/projects with a name, or push-to-create) where the resolved parent path is null (root-level project), the project does not already exist, and the authenticated subject lacks the 'Create Root Projects' privilege.

Common situations: A regular user (not a session/user with administrator or explicitly granted 'Create Root Projects') tries to create a top-level project via the REST API, CLI, or git push-to-create; CI jobs using a token whose owner lacks the permission attempt to provision a root project; an admin removed the permission but scripts still reference old behavior.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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