{"record":{"id":"d12fd6eb9cef3b62","repo":"theonedev/onedev","slug":"no-package-write-permission-for-project-project-d12fd6","errorCode":null,"errorMessage":"No package write permission for project: ${project.path}","messagePattern":"No package write permission for project: (.+?)","errorType":"exception","errorClass":"UnauthorizedException","httpStatus":null,"severity":"error","filePath":"server-plugin/server-plugin-pack-container/src/main/java/io/onedev/server/plugin/pack/container/ContainerServlet.java","lineNumber":520,"sourceCode":"\t}\n\t\n\tprivate Digest parseDigest(String digestString) {\n\t\tif (digestString.startsWith(\"sha256:\")) {\n\t\t\treturn new Digest(SHA256, digestString.substring(\"sha256:\".length()));\n\t\t} else {\n\t\t\tthrow new ClientException(SC_NOT_ACCEPTABLE, ErrorCode.UNSUPPORTED, \n\t\t\t\t\t\"Unsupported digest: \" + digestString);\n\t\t}\n\t}\n\t\n\tprivate Project checkProject(String projectPath, boolean needsToPush) {\n\t\tvar project = projectService.findByPath(projectPath);\n\t\tif (project == null) \n\t\t\tthrow new NotFoundException(ErrorCode.NAME_UNKNOWN, \"Unknown project: \" + projectPath);\n\t\telse if (!project.isPackManagement())\n\t\t\tthrow new ClientException(SC_NOT_ACCEPTABLE, ErrorCode.DENIED, \"Package management not enabled for project: \" + projectPath);\n\t\telse if (needsToPush && !SecurityUtils.canWritePack(project))\n\t\t\tthrow new UnauthorizedException(\"No package write permission for project: \" + project.getPath());\n\t\telse if (!needsToPush && !SecurityUtils.canReadPack(project))\n\t\t\tthrow new UnauthorizedException(\"No package read permission for project: \" + project.getPath());\n\t\telse\n\t\t\treturn project;\n\t}\n\n\tprivate String getChallenge() {\n\t\tvar serverUrl = settingService.getSystemSetting().getServerUrl();\n\t\treturn \"Bearer realm=\\\"\" + serverUrl + \"/v2/token\\\",service=\\\"onedev\\\",scope=\\\"*\\\"\";\n\t}\n\t\n}\n","sourceCodeStart":502,"sourceCodeEnd":533,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-container/src/main/java/io/onedev/server/plugin/pack/container/ContainerServlet.java#L502-L533","documentation":"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.","triggerScenarios":"docker push (or blob/manifest upload endpoints) where the logged-in account has read-only or no pack access to the target project.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// check effective write permission before pushing (as the CI user)\ncurl -u user:token https://onedev.example.com/api/projects/<id>/permissions","typeGuard":null,"tryCatchPattern":"try { push() } catch (e) { if (e instanceof UnauthorizedException && /write permission/.test(e.message)) { requestPackWriteAccess(); } else { throw e; } }","preventionTips":["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."],"tags":["container-registry","authorization","permissions"],"backgroundTag":"permission-denied","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}