theonedev/onedev · error · UnauthorizedException
Unauthorized
Error message
Unauthorized
What it means
After the build is found, BuildLogResource enforces SecurityUtils.canAccessLog(build); users who can see the project but not its build logs (e.g. restricted roles) get UnauthorizedException, surfaced as HTTP 401/403 with message "Unauthorized".
Source
Thrown at server-core/src/main/java/io/onedev/server/web/resource/BuildLogResource.java:66
PageParameters params = attributes.getParameters();
Long projectId = params.get(PARAM_PROJECT).toLong();
Long buildNumber = params.get(PARAM_BUILD).toOptionalLong();
if (buildNumber == null)
throw new IllegalArgumentException("build number has to be specified");
if (!SecurityUtils.isSystem()) {
Project project = getProjectService().load(projectId);
Build build = getBuildService().find(project, buildNumber);
if (build == null) {
String message = String.format("Unable to find build (project: %s, build number: %d)",
project.getPath(), buildNumber);
throw new EntityNotFoundException(message);
}
if (!SecurityUtils.canAccessLog(build))
throw new UnauthorizedException();
}
ResourceResponse response = new ResourceResponse();
response.setContentType(MimeTypes.OCTET_STREAM);
response.disableCaching();
try {
response.setFileName(URLEncoder.encode("build-log.txt", StandardCharsets.UTF_8.name()));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
response.setWriteCallback(new WriteCallback() {
@Override
public void writeData(Attributes attributes) throws IOException {
String activeServer = getProjectService().getActiveServer(projectId, true);
var clusterService = getClusterService();View on GitHub (pinned to d44925c47c)
Solutions
- Request/grant the role that includes access to build logs for the project (Project > Access Control).
- Log in with an authorized account instead of anonymous access.
- For CI scripts, use an access token whose role permits log access.
Example fix
// before: guest token fetching logs -> 401 curl -H "Authorization: Bearer $GUEST_TOKEN" .../buildlogs?project=1&build=42 // after: token role includes log access curl -H "Authorization: Bearer $CI_TOKEN" .../buildlogs?project=1&build=42
Defensive patterns
Strategy: try-catch
Validate before calling
// confirm the caller's role grants log access before attempting
canAccessLog = userRoles.some(r => r.project === projectId && r.permissions.includes('VIEW_BUILD_LOGS')); Try / catch
try { downloadLog(url); } catch (HttpException e) { if (e.getStatusCode() === 403) { requestLogAccess(project); } else throw e; } Prevention
- Grant log-view permission to roles that consume CI output programmatically
- Use dedicated CI tokens with the right role
- Audit role permissions after access-model changes
When it happens
Trigger: GET /~resource/buildlogs?project=..&build=.. with an existing build while the authenticated user (or anonymous) lacks log access permission on that build/project.
Common situations: Guest users opening direct log links shared by developers; service accounts whose role allows running pipelines but not viewing logs; permission model changes removing 'View build logs' from a role.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- build number has to be specified
- Unable to find build (project: %s, build number: %d)
- Unauthorized
- Issue schedule permission required to set iterations
- No permission to update issue fields
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/a92f06dfbf7ed3f4.
Report an issue: GitHub.