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

  1. Use resources belonging to the requesting user's own tenant (path prefix must equal the user's tenantCode).
  2. Ask an administrator to move/copy the resource into your tenant's directory if access is legitimately needed.
  3. If the user's tenant changed recently, re-create resources under the new tenant and update workflow references.
  4. 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

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


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/f1f36b6eabc03225. Report an issue: GitHub.