{"record":{"id":"88f94f4fb85dd55c","repo":"theonedev/onedev","slug":"authentication-required-88f94f","errorCode":null,"errorMessage":"Authentication required","messagePattern":"Authentication required","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/git/GitFilter.java","lineNumber":111,"sourceCode":"\t\n\tprivate Long getProjectId(String projectPath, boolean clusterAccess, boolean upload) {\n\t\tvar facade = projectService.findFacadeByPath(projectPath);\n\t\tif (facade == null && projectPath.endsWith(\".git\")) {\n\t\t\tprojectPath = StringUtils.substringBeforeLast(projectPath, \".\");\n\t\t\tfacade = projectService.findFacadeByPath(projectPath);\n\t\t}\n\t\tif (StringUtils.isBlank(projectPath))\n\t\t\tthrow new ExplicitException(\"Project not specified\");\n\t\tif (facade == null) \n\t\t\treportProjectNotFoundOrInaccessible(projectPath);\n\t\treturn facade.getId();\n\t}\n\n\tprivate void reportProjectNotFoundOrInaccessible(String projectPath) {\n\t\tif (SecurityUtils.getUser() != null)\n\t\t\tthrow new EntityNotFoundException(\"Project not found or inaccessible: \" + projectPath);\n\t\telse\n\t\t\tthrow new UnauthorizedException(\"Authentication required\");\n\t}\n\n\tprivate void doNotCache(HttpServletResponse response) {\n\t\tresponse.setHeader(\"Expires\", \"Fri, 01 Jan 1980 00:00:00 GMT\");\n\t\tresponse.setHeader(\"Pragma\", \"no-cache\");\n\t\tresponse.setHeader(\"Cache-Control\", \"no-cache, max-age=0, must-revalidate\");\n\t}\n\n\tprotected void processPack(final HttpServletRequest request, final HttpServletResponse response) \n\t\t\tthrows IOException, InterruptedException, ExecutionException {\n\t\tboolean upload = GitSmartHttpTools.isUploadPack(request);\n\t\t\n\t\tString pathInfo = getPathInfo(request);\t\n\t\tString service = StringUtils.substringAfterLast(pathInfo, \"/\");\n\t\tString projectInfo = StringUtils.substringBeforeLast(pathInfo, \"/\");\n\n\t\tString principal = (String) SecurityUtils.getSubject().getPrincipal();\n\t\tboolean clusterAccess = SecurityUtils.isSystem(principal);","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/git/GitFilter.java#L93-L129","documentation":"When the same lookup fails (project not found or inaccessible) but SecurityUtils.getUser() is null — i.e. the request carries no authentication at all — GitFilter throws UnauthorizedException(\"Authentication required\") instead of entity-not-found. This steers anonymous clients toward authenticating rather than leaking project existence.","triggerScenarios":"Any git smart-HTTP request (refs/pack) from an unauthenticated session whose project path does not resolve; typical when credentials are absent, the access token expired, or the credential helper stopped supplying credentials.","commonSituations":"Clone/fetch from CI without configured credentials; expired or revoked access token in the remote URL; credential helper not initialized; anonymous access disabled on the server while the project is not public.","solutions":["Authenticate: embed a valid access token or use a credential helper (git config credential.helper) before cloning","Regenerate an expired/revoked access token and update the remote","If the project is meant to be public, grant anonymous read access in project settings","Run git fetch manually to trigger the credential prompt and store credentials"],"exampleFix":"// before\ngit clone https://onedev.example.com/privateproject.git\n\n// after\ngit clone https://oauth2:<access-token>@onedev.example.com/privateproject.git","handlingStrategy":"validation","validationCode":"if (!accessToken || isExpired(accessToken)) {\n  throw new Error('Provide a valid OneDev access token before git operations');\n}","typeGuard":null,"tryCatchPattern":"try {\n  git.clone(url);\n} catch (UnauthorizedException e) {\n  if (e.getMessage().equals(\"Authentication required\")) {\n    promptForCredentialsAndRetry();\n  }\n}","preventionTips":["Configure a credential helper or embed a valid access token in CI","Rotate access tokens before expiry","Test anonymous access expectations: private projects always require credentials"],"tags":["git","http","authentication","onedev"],"backgroundTag":"authentication-required","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"}