theonedev/onedev · error · ExplicitException

Cannot create this branch as branch protection setting requi

Error message

Cannot create this branch as branch protection setting requires valid signature on head commit

What it means

POST /{projectId}/branches throws ExplicitException when branch protection requires a valid signature on the head commit but the commit pointed to by the requested revision is unsigned or has an invalid signature. OneDev refuses to point the protected branch at an unverified commit.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/RepositoryResource.java:165

	}

	@Api(order=30, description="Create a new branch")
	@Path("/{projectId}/branches")
	@POST
	public Response createBranch(@PathParam("projectId") Long projectId, @NotNull CreateBranchRequest request) {
		Project project = projectService.load(projectId);
		User user = SecurityUtils.getUser();
		if (!SecurityUtils.canWriteCode(project)) 
			throw new UnauthorizedException();
		else if (project.getBranchRef(request.getBranchName()) != null) 
			throw new NotAcceptableException("Branch '" + request.getBranchName() + "' already exists");
		else if (project.getBranchProtection(request.getBranchName(), user).isPreventCreation()) 
			throw new ExplicitException("Branch creation prohibited by branch protection rule");
		
		if (!project.isCommitSignatureRequirementSatisfied(
				user, request.getBranchName(), 
				project.getRevCommit(request.getRevision(), true))) {
			throw new ExplicitException("Cannot create this branch as branch protection setting "
					+ "requires valid signature on head commit");
		}
		
		gitService.createBranch(project, request.getBranchName(), request.getRevision());

		return Response.ok().build();
	}

	@Api(order=40, description="Delete specified branch")
	@Path("/{projectId}/branches/{branch:.*}")
	@DELETE
	public Response deleteBranch(@PathParam("projectId") Long projectId, 
			@PathParam("branch") @Api(example="test-branch") String branchName) {
		Project project = projectService.load(projectId);
		if (!SecurityUtils.canDeleteBranch(project, branchName)) 
			throw new UnauthorizedException();
		
		projectService.deleteBranch(project, branchName);

View on GitHub (pinned to d44925c47c)

Solutions

  1. Create the branch from a signed commit (git commit -S locally configured with a trusted key)
  2. Ask an admin to disable the signature requirement for that branch pattern
  3. Sign and re-push the head commit (rebase or amend with signing) then use its hash as revision

Example fix

// before
git commit -m "wip" // unsigned
POST /~api/1/branches {"branchName":"dev","revision":"HEAD"}
// after
git commit -S -m "wip" && git push
POST /~api/1/branches {"branchName":"dev","revision":"<signed-commit-hash>"}
Defensive patterns

Strategy: validation

Validate before calling

// verify head commit signature locally before branching
git verify-commit <hash> || echo 'signature invalid; branch creation will be rejected'

Try / catch

try {
  createBranch(projectId, req);
} catch (ExplicitException e) {
  // instruct user to branch from a signed commit
}

Prevention

When it happens

Trigger: Calling POST /~api/{projectId}/branches with a revision whose head commit fails project.isCommitSignatureRequirementSatisfied for the acting user, because commit signing is required for that branch pattern.

Common situations: Branching from a merge bot commit or CI-generated commit that is unsigned; commits made locally without gpg/ssh signing configured; signatures from untrusted keys.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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