apolloconfig/apollo · error · ServiceException

namespace not unique

Error message

namespace not unique

What it means

Thrown as ServiceException (HTTP 500) by NamespaceService.save when isNamespaceUnique(appId, clusterName, namespaceName) is false — the same appId+clusterName+namespaceName combination already exists. Note it surfaces as a 500 ServiceException rather than a 400, which is a known code smell: a duplicate/conflict is reported as a server error.

Source

Thrown at apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/NamespaceService.java:359

    namespace.setDataChangeLastModifiedBy(operator);

    auditService.audit(Namespace.class.getSimpleName(), namespace.getId(), Audit.OP.DELETE,
        operator);

    Namespace deleted = namespaceRepository.save(namespace);

    // Publish release message to do some clean up in config service, such as updating the cache
    messageSender.sendMessage(
        ReleaseMessageKeyGenerator.generate(appId, clusterName, namespaceName),
        Topics.APOLLO_RELEASE_TOPIC);

    return deleted;
  }

  @Transactional
  public Namespace save(Namespace entity) {
    if (!isNamespaceUnique(entity.getAppId(), entity.getClusterName(), entity.getNamespaceName())) {
      throw new ServiceException("namespace not unique");
    }

    if (bizConfig.isNamespaceNumLimitEnabled()
        && !bizConfig.namespaceNumLimitWhite().contains(entity.getAppId())) {
      int nowCount = namespaceRepository.countByAppIdAndClusterName(entity.getAppId(),
          entity.getClusterName());
      if (nowCount >= bizConfig.namespaceNumLimit()) {
        throw new ServiceException(
            "namespace[appId = " + entity.getAppId() + ", cluster= " + entity.getClusterName()
                + "] nowCount= " + nowCount + ", maxCount =" + bizConfig.namespaceNumLimit());
      }
    }

    entity.setId(0);// protection
    Namespace namespace = namespaceRepository.save(entity);

    auditService.audit(Namespace.class.getSimpleName(), namespace.getId(), Audit.OP.INSERT,
        namespace.getDataChangeCreatedBy());

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Check existence first with namespaceService.findOne(appId, clusterName, namespaceName) and return the existing one instead of re-saving.
  2. Make provisioning scripts idempotent (skip-if-exists).
  3. Treat this as a 409/400 conflict at the controller layer; consider upstream improvement to throw a conflict-style exception.

Example fix

// before
namespaceService.save(newNamespace); // throws 'namespace not unique' if exists
// after
Namespace existing = namespaceService.findOne(appId, clusterName, name);
if (existing != null) {
  return existing;
}
return namespaceService.save(newNamespace);
Defensive patterns

Strategy: validation

Validate before calling

Namespace existing = namespaceService.findOne(entity.getAppId(),
    entity.getClusterName(), entity.getNamespaceName());
if (existing != null) {
  return existing; // idempotent
}
return namespaceService.save(entity);

Try / catch

try {
  return namespaceService.save(entity);
} catch (ServiceException e) {
  if ("namespace not unique".equals(e.getMessage())) {
    return namespaceService.findOne(entity.getAppId(), entity.getClusterName(), entity.getNamespaceName());
  }
  throw e;
}

Prevention

When it happens

Trigger: Creating a namespace via NamespaceService.save when an identical (appId, clusterName, namespaceName) namespace already exists, or two concurrent creates race past the uniqueness check before the DB unique constraint catches one.

Common situations: Idempotent re-creation after a retry; scripts that re-run namespace provisioning; a duplicate detected at the service layer rather than the DB.

Related errors


AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14). Data as JSON: /api/errors/33a5afac124cf587. Report an issue: GitHub.