apache/dolphinscheduler · error · ServiceException
20016
20016
Error message
resource not exist or no permission,please view the task node and remove error resource
What it means
ServiceException(Status.RESOURCE_NOT_EXIST_OR_NO_PERMISSION, 20016) is thrown when the resource file IDs attached to the task definition fail the PermissionCheck (AuthorizationType.RESOURCE_FILE_ID) during an ONLINE release. Either a referenced resource no longer exists or the releasing user lacks permission on it.
Source
Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskDefinitionServiceImpl.java:375
taskDefinition.setFlag(Flag.NO);
taskDefinitionLog.setFlag(Flag.NO);
break;
case ONLINE:
taskDatasourcePermissionChecker.checkPermission(loginUser,
Collections.singletonList(taskDefinitionLog));
taskSubWorkflowPermissionChecker.checkPermission(loginUser,
Collections.singletonList(taskDefinitionLog));
String resourceIds = taskDefinition.getResourceIds();
if (StringUtils.isNotBlank(resourceIds)) {
Integer[] resourceIdArray =
Arrays.stream(resourceIds.split(",")).map(Integer::parseInt).toArray(Integer[]::new);
PermissionCheck<Integer> permissionCheck = new PermissionCheck(AuthorizationType.RESOURCE_FILE_ID,
processService, resourceIdArray, loginUser.getId(), log);
try {
permissionCheck.checkPermission();
} catch (Exception e) {
log.error("Resources permission check error, resourceIds:{}.", resourceIds, e);
throw new ServiceException(Status.RESOURCE_NOT_EXIST_OR_NO_PERMISSION);
}
}
taskDefinition.setFlag(Flag.YES);
taskDefinitionLog.setFlag(Flag.YES);
break;
default:
log.warn("Parameter releaseState is invalid.");
throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, Constants.RELEASE_STATE);
}
boolean updateSuccess = taskDefinitionDao.updateById(taskDefinition);
int updateLog = taskDefinitionLogMapper.updateById(taskDefinitionLog);
if (updateSuccess != (updateLog == 1)) {
log.error("Update taskDefinition state or taskDefinitionLog state error, taskDefinitionCode:{}.", code);
throw new ServiceException(Status.UPDATE_TASK_DEFINITION_ERROR);
}
log.info("Update taskDefinition state or taskDefinitionLog state to complete, taskDefinitionCode:{}.",
code);
}View on GitHub (pinned to 02eac45a1b)
Solutions
- Open the task definition and remove/replace the stale resource references in the task node
- Re-upload the missing resource file and re-link it, ensuring the current user has access
- Grant loginUser permission on the referenced resource files, then retry the release
- Audit all task definitions for dangling resourceIds after resource cleanup
Example fix
// before: releasing with stale resourceIds resourceIds: "10001,10002" // 10002 deleted // after: remove the deleted id (or re-add the resource) before releasing resourceIds: "10001"
Defensive patterns
Strategy: validation
Validate before calling
List<Integer> ids = Arrays.stream(resourceIds.split(",")).map(Integer::parseInt).collect(toList());
List<Resource> owned = resourceService.authorizedResourceFiles(loginUser.getId());
List<Integer> missing = ids.stream().filter(id -> owned.stream().noneMatch(r -> r.getId().equals(id))).collect(toList());
if (!missing.isEmpty()) throw new IllegalStateException("missing/unauthorized resources: " + missing); Type guard
boolean allResourcesAuthorized(User user, List<Integer> resourceIds) {
return resourceService.authorizedResourceFiles(user.getId()).stream()
.map(Resource::getId).collect(toSet()).containsAll(resourceIds);
} Try / catch
try {
service.releaseTaskDefinition(loginUser, projectCode, code, ReleaseState.ONLINE);
} catch (ServiceException e) {
if (e.getCode() == Status.RESOURCE_NOT_EXIST_OR_NO_PERMISSION.getCode()) { /* edit task node to drop stale resources */ }
throw e;
} Prevention
- Before deleting a resource file, search tasks referencing its id
- Re-check resource permissions whenever users/tenants change
- After environment migrations, validate all resourceIds resolve
- Run PermissionCheck-equivalent pre-validation before releasing workflows
When it happens
Trigger: releaseTaskDefinition with releaseState=ONLINE where the task definition's resourceIds reference resource files that were deleted, moved, or are not owned/authorized for loginUser.getId().
Common situations: An admin deleted a shared resource file that workflow tasks still reference; user account changed (different tenant/permissions) since the task was authored; environment migration left resource IDs dangling.
Related errors
- USER_NO_OPERATION_PERM
- 50038
- Thr resource is not exists: ${resourceAbsolutePath}
- The resource is already exist: ${resourceAbsolutePath}
- The path is not a directory: ${resourceAbsolutePath}
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/7f168510008ecb97.
Report an issue: GitHub.