theonedev/onedev · error · UnauthorizedException
No package write permission for project: ${project.path}
Error message
No package write permission for project: ${project.path} What it means
When the registry operation requires push rights (needsToPush) and the authenticated user lacks pack write permission on the project, checkProject throws UnauthorizedException. The user is authenticated but not authorized to write packages to this project.
Source
Thrown at server-plugin/server-plugin-pack-container/src/main/java/io/onedev/server/plugin/pack/container/ContainerServlet.java:520
}
private Digest parseDigest(String digestString) {
if (digestString.startsWith("sha256:")) {
return new Digest(SHA256, digestString.substring("sha256:".length()));
} else {
throw new ClientException(SC_NOT_ACCEPTABLE, ErrorCode.UNSUPPORTED,
"Unsupported digest: " + digestString);
}
}
private Project checkProject(String projectPath, boolean needsToPush) {
var project = projectService.findByPath(projectPath);
if (project == null)
throw new NotFoundException(ErrorCode.NAME_UNKNOWN, "Unknown project: " + projectPath);
else if (!project.isPackManagement())
throw new ClientException(SC_NOT_ACCEPTABLE, ErrorCode.DENIED, "Package management not enabled for project: " + projectPath);
else if (needsToPush && !SecurityUtils.canWritePack(project))
throw new UnauthorizedException("No package write permission for project: " + project.getPath());
else if (!needsToPush && !SecurityUtils.canReadPack(project))
throw new UnauthorizedException("No package read permission for project: " + project.getPath());
else
return project;
}
private String getChallenge() {
var serverUrl = settingService.getSystemSetting().getServerUrl();
return "Bearer realm=\"" + serverUrl + "/v2/token\",service=\"onedev\",scope=\"*\"";
}
}
View on GitHub (pinned to d44925c47c)
Solutions
- Grant the user/service account pack write (manage package) permission on the project.
- Log in with an account that has write access (docker login with correct credentials).
- If using a CI job secret/token, regenerate it with write package permissions.
Defensive patterns
Strategy: validation
Validate before calling
// check effective write permission before pushing (as the CI user) curl -u user:token https://onedev.example.com/api/projects/<id>/permissions
Try / catch
try { push() } catch (e) { if (e instanceof UnauthorizedException && /write permission/.test(e.message)) { requestPackWriteAccess(); } else { throw e; } } Prevention
- Provision dedicated service accounts with pack write role for CI publishing.
- Regenerate CI tokens with package write scope.
- Verify with `docker login` + a dry-run that credentials can write before pipelines.
When it happens
Trigger: docker push (or blob/manifest upload endpoints) where the logged-in account has read-only or no pack access to the target project.
Common situations: CI service account without write pack role; user added to project with read-only role; personal access token lacking package write scope; push to another team's project by mistake.
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
- No package read permission for project: ${project.path}
- Access denied
- Issue schedule permission required to set own estimated time
- Issue schedule permission required to set iterations
- No permission to access issue: ${referenceString}
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/d12fd6eb9cef3b62.
Report an issue: GitHub.