theonedev/onedev · error · UnauthorizedException
Not authorized
Error message
Not authorized
What it means
createWorkspace throws UnauthorizedException when there is no authenticated user on the request subject. Workspace creation requires a real user identity; anonymous or token-less requests cannot create workspaces. This is the first of two authorization checks in the endpoint.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/WorkspaceResource.java:104
@QueryParam("query") @Api(description="Syntax of this query is the same as in <a href='/~workspaces'>workspaces page</a>", example="active") String query,
@QueryParam("offset") @Api(example="0") int offset,
@QueryParam("count") @Api(example="100") int count) {
var subject = SecurityUtils.getSubject();
if (!SecurityUtils.isAdministrator(subject) && count > RestConstants.MAX_PAGE_SIZE)
throw new NotAcceptableException("Count should not be greater than " + RestConstants.MAX_PAGE_SIZE);
var parsedQuery = WorkspaceQuery.parse(null, query, true);
return workspaceService.query(subject, null, parsedQuery, offset, count);
}
@Api(order=300, description="Create new workspace")
@POST
public Long createWorkspace(@NotNull @Valid WorkspaceCreateData data) {
var subject = SecurityUtils.getSubject();
var user = SecurityUtils.getUser(subject);
if (user == null)
throw new UnauthorizedException();
Project project = projectService.load(data.getProjectId());
if (!SecurityUtils.canCreateWorkspaces(subject, project))
throw new UnauthorizedException();
if (project.getHierarchyWorkspaceSpecs().stream()
.noneMatch(it -> it.getName().equals(data.getSpecName()))) {
throw new NotAcceptableException("Workspace spec not found: " + data.getSpecName());
}
ObjectId commitId = ObjectId.fromString(data.getCommitHash());
var commit = project.getRevCommit(commitId, false);
if (commit == null)
throw new NotAcceptableException("Commit not found: " + data.getCommitHash());
Issue issue = null;
if (data.getIssueId() != null) {
issue = issueService.get(data.getIssueId());View on GitHub (pinned to d44925c47c)
Solutions
- Send a valid Authorization header with a personal access token of a real user
- Verify the token works via GET /users/me before calling the endpoint
- Re-generate the access token if it was revoked or expired
Example fix
// before
post("/workspaces", data); // no auth
// after
post("/workspaces", data, auth: bearerToken(userAccessToken)); Defensive patterns
Strategy: validation
Validate before calling
User me = tryGetAuthenticatedUser(); if (me == null) throw new IllegalStateException("no valid credentials"); Type guard
boolean hasUserIdentity(Subject s) { return SecurityUtils.getUser(s) != null; } Try / catch
try { createWorkspace(data); } catch (UnauthorizedException e) { throw new ConfigurationException("invalid or missing access token"); } Prevention
- Always attach a valid user access token to API calls
- Validate tokens with GET /users/me before workflows
- Rotate tokens before expiry and never strip the Authorization header
When it happens
Trigger: POSTing to /workspaces without credentials, or with a token/job credential that does not resolve to a User (SecurityUtils.getUser(subject) returns null).
Common situations: Calling the API with a malformed or revoked access token; missing Authorization header in a script; using a machine credential that authenticates but carries no user identity.
Related errors
- No permission to access build: ${referenceString}
- Not authorized
- Not authorized
- Unauthorized
- Unauthorized
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/b4679fc4cb6a8fb8.
Report an issue: GitHub.