apache/shenyu · error · ShenyuAdminException

metaData exist under those namespace!

Error message

metaData exist under those namespace!

What it means

ShenYu admin refuses to delete a namespace while metadata rows still reference it. Metadata (API metadata registered by backend clients) must be removed before the namespace can be deleted; otherwise the delete is aborted with this ShenyuAdminException.

Solutions

  1. Unregister the backend clients / delete metadata under the namespace first
  2. Delete the metadata entries via the dashboard metadata page or metadata service API
  3. Check the metadata table for the namespaceIds and remove those rows, then retry

Example fix

// before
namespaceService.delete(Arrays.asList("ns-prod")); // throws: metaData exist under those namespace!
// after
metaDataService.deleteByNamespace("ns-prod"); // remove registered metadata first
namespaceService.delete(Arrays.asList("ns-prod"));
Defensive patterns

Strategy: validation

Validate before calling

if (metaDataMapper.findAllByNamespaceIds(namespaceIds).isEmpty()) {
    namespaceService.delete(namespaceIds);
}

Try / catch

try {
    namespaceService.delete(namespaceIds);
} catch (ShenyuAdminException e) {
    if (e.getMessage().contains("metaData exist")) {
        // deregister clients / delete metadata, then retry
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling NamespaceService.delete when metaDataMapper.findAllByNamespaceIds returns rows for the target namespaces. Rules, selectors and plugin relations must already be empty for the flow to reach this check.

Common situations: Deleting a namespace whose backend services are still registered (clients auto-register metadata via shenyu-register-center); decommissioning a namespace before unregistering/deregistering its API clients.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/5970efcd176284ac. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/NamespaceServiceImpl.java:157

        List<String> namespaceIdList = namespaceMapper.selectByIds(ids).stream().map(NamespaceDO::getNamespaceId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(namespaceIdList)) {
            throw new ShenyuAdminException(AdminConstants.SYS_NAMESPACE_ID_NOT_EXIST);
        }
        List<RuleDO> ruleDOList = ruleMapper.selectAllByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(ruleDOList)) {
            throw new ShenyuAdminException("rule exist under those namespace!");
        }
        List<SelectorDO> selectorDOS = selectorMapper.selectAllByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(selectorDOS)) {
            throw new ShenyuAdminException("selector exist under those namespace!");
        }
        List<NamespacePluginVO> namespacePluginVOS = namespacePluginRelMapper.selectAllByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(namespacePluginVOS)) {
            throw new ShenyuAdminException("Plugins exist under those namespace!");
        }
        List<MetaDataDO> metaDataDOList = metaDataMapper.findAllByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(metaDataDOList)) {
            throw new ShenyuAdminException("metaData exist under those namespace!");
        }
        List<AppAuthDO> appPathDOList = appAuthMapper.findByNamespaceIds(namespaceIdList);
        if (CollectionUtils.isNotEmpty(appPathDOList)) {
            throw new ShenyuAdminException("appPath exist under those namespace!");
        }
        namespaceMapper.deleteByIds(ids);
        return ShenyuResultMessage.DELETE_SUCCESS;
    }

    @Override
    public NamespaceVO findById(final String id) {
        return NamespaceTransfer.INSTANCE.mapToVo(namespaceMapper.selectById(id));
    }

    @Override
    public NamespaceVO findByNamespaceId(final String namespaceId) {
        return NamespaceTransfer.INSTANCE.mapToVo(namespaceMapper.selectByNamespaceId(namespaceId));
    }

View on GitHub (pinned to 567142e072)