theonedev/onedev · error · UnauthorizedException

You do not have permission to pull from this project.

Error message

You do not have permission to pull from this project.

What it means

checkPullPermission verifies, after canAccessProject passes, that the requester may pull code from the project — either via SecurityUtils.canReadCode or by matching a registered CodePullAuthorizationSource that authorizes the request. If no path authorizes, it throws this UnauthorizedException. It protects read access to repository data over git HTTP.

Source

Thrown at server-core/src/main/java/io/onedev/server/git/GitFilter.java:271

		response.setHeader("Content-Type", "application/x-" + service + "-advertisement");			
		
		PacketLineOut pack = new PacketLineOut(response.getOutputStream());
		pack.setFlushOnEnd(false);
		pack.writeString("# service=" + service + "\n");
		pack.end();
	}
	
	private void checkPullPermission(HttpServletRequest request, Project project) {
		if (!SecurityUtils.canReadCode(project)) {
			boolean isAuthorized = false;
			for (CodePullAuthorizationSource source: codePullAuthorizationSources) {
				if (source.canPullCode(request, project)) {
					isAuthorized = true;
					break;
				}
			}
			if (!isAuthorized)
				throw new UnauthorizedException("You do not have permission to pull from this project.");
		}
	}

	private void checkPushPermission(HttpServletRequest request, Project project) {
		if (!SecurityUtils.canWriteCode(project)) 
			throw new UnauthorizedException("You do not have permission to push to this project.");
	}

	private boolean canAccessProject(HttpServletRequest request, Project project) {
		if (!SecurityUtils.canAccessProject(project)) {
			for (CodePullAuthorizationSource source: codePullAuthorizationSources) {
				if (source.canPullCode(request, project)) 
					return true;
			}
			return false;
		} else {
			return true;
		}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Ask a project admin to grant your role the 'Read code' permission
  2. Use an access token created by a user/job with code read permission
  3. If cloning for PR builds, ensure the PR authorization context (job token) is used so canPullCode applies
  4. Verify the clone targets the correct project you actually have access to

Example fix

// before: job token without code read
curl https://onedev.example.com/myproject.git/info/refs?service=git-upload-pack

// after: use a token of a user with 'Read code'
git clone https://oauth2:<token-with-read-code>@onedev.example.com/myproject.git
Defensive patterns

Strategy: try-catch

Validate before calling

// Check role permission via REST before cloning
const me = await fetch(`${server}/api/projects/${projectId}/authorizations`);
// ensure 'Read code' is present for your role

Try / catch

try {
  git.clone(url);
} catch (UnauthorizedException e) {
  if (e.getMessage().contains("permission to pull")) {
    requestAccessFromProjectAdmin(project);
  }
}

Prevention

When it happens

Trigger: processRefs or processPack (fetch/clone) on a project the authenticated user can technically reach but lacks code-read permission on, and no CodePullAuthorizationSource (e.g. pull-request build authorization) grants access via canPullCode.

Common situations: CI job clone with a token lacking code-read scope; user added to project without code read role; trying to fetch a dependency repo not covered by your permissions; pull-request authorization source not matching because the request lacks the PR context.

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/523413ac5d91c325. Report an issue: GitHub.