apache/dolphinscheduler · error · ServiceException
The user's tenant is ${userTenant} have no permission to acc
Error message
The user's tenant is ${userTenant} have no permission to access the resource: ${resourceAbsolutePath} What it means
exceptionUserNoResourcePermission throws this ServiceException when the tenant code parsed from the resource path does not match the login user's tenant, so the user is not allowed to access another tenant's resources.
Source
Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/validator/resource/AbstractResourceValidator.java:132
public void exceptionUserNoResourcePermission(User user, String resourceAbsolutePath) {
if (user.getUserType() == UserType.ADMIN_USER) {
return;
}
// check if the user have resource tenant permission
// Parse the resource path to get the tenant code
ResourceMetadata resourceMetaData = storageOperator.getResourceMetaData(resourceAbsolutePath);
if (!resourceAbsolutePath.startsWith(resourceMetaData.getResourceBaseDirectory())) {
throw new ServiceException("Invalidated resource path: " + resourceAbsolutePath);
}
// todo: inject the tenant when login
Tenant tenant = tenantDao.queryOptionalById(user.getTenantId())
.orElseThrow(() -> new ServiceException(Status.TENANT_NOT_EXIST, user.getTenantId()));
String userTenant = tenant.getTenantCode();
if (!userTenant.equals(resourceMetaData.getTenant())) {
throw new ServiceException(
"The user's tenant is " + userTenant + " have no permission to access the resource: "
+ resourceAbsolutePath);
}
}
}
View on GitHub (pinned to 02eac45a1b)
Solutions
- Use resources belonging to the requesting user's own tenant (path prefix must equal the user's tenantCode).
- Ask an administrator to move/copy the resource into your tenant's directory if access is legitimately needed.
- If the user's tenant changed recently, re-create resources under the new tenant and update workflow references.
- Verify the user's tenant assignment in Security > Tenant Management.
Example fix
// before: accessing another tenant's file readResource(loginUserOfTenantA, "/tenantB/resources/job.sql", 0, -1); // after readResource(loginUserOfTenantA, "/tenantA/resources/job.sql", 0, -1);
Defensive patterns
Strategy: try-catch
Validate before calling
String tenantFromPath = path.split("/")[1]; if (!tenantFromPath.equals(currentUserTenantCode)) { throw new SecurityException("Cross-tenant access denied: " + path); } Try / catch
try { resourceOp(path); } catch (ServiceException e) { if (e.getMessage().contains("have no permission to access the resource")) { /* show access-denied UI, offer to request access */ } else { throw e; } } Prevention
- Only operate on resources whose path tenant segment equals the user's tenant.
- After tenant changes, migrate resources and update workflow references.
- Never share cross-tenant resource URLs between users.
When it happens
Trigger: A user of tenant A requests read/write/delete on a resource whose absolute path resolves to tenant B (e.g. '/tenantB/resources/job.sh'), via any validated resource API.
Common situations: Sharing paths between users of different tenants; an admin changing a user's tenant while old workflows still reference the previous tenant's paths; copying resource URLs between environments/tenants.
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
- 20016
- user %s doesn't have permission of %s %s
- Can not create or update workflow for user who not related t
- Can not find valid resource by name %s
- USER_NO_OPERATION_PERM
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/f1f36b6eabc03225.
Report an issue: GitHub.