{"record":{"id":"72b980e5e195cc0e","repo":"apache/dolphinscheduler","slug":"10009","errorCode":"10009","errorMessage":"os tenant code {tenantCode} already exists","messagePattern":"os tenant code (.+?) already exists","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TenantServiceImpl.java","lineNumber":94,"sourceCode":"    private UserDao userDao;\n\n    @Autowired\n    private QueueService queueService;\n\n    /**\n     * Check the tenant new object valid or not\n     *\n     * @param tenant The tenant object want to create\n     */\n    private void createTenantValid(Tenant tenant) throws ServiceException {\n        if (StringUtils.isEmpty(tenant.getTenantCode())) {\n            throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, tenant.getTenantCode());\n        } else if (StringUtils.length(tenant.getTenantCode()) > TENANT_FULL_NAME_MAX_LENGTH) {\n            throw new ServiceException(Status.TENANT_FULL_NAME_TOO_LONG_ERROR);\n        } else if (!RegexUtils.isValidLinuxUserName(tenant.getTenantCode())) {\n            throw new ServiceException(Status.CHECK_OS_TENANT_CODE_ERROR);\n        } else if (checkTenantExists(tenant.getTenantCode())) {\n            throw new ServiceException(Status.OS_TENANT_CODE_EXIST, tenant.getTenantCode());\n        }\n    }\n\n    /**\n     * Check tenant update object valid or not\n     *\n     * @param existsTenant The exists queue object\n     * @param updateTenant The queue object want to update\n     */\n    private void updateTenantValid(Tenant existsTenant, Tenant updateTenant) throws ServiceException {\n        // Check the exists tenant\n        if (Objects.isNull(existsTenant)) {\n            log.error(\"Tenant does not exist.\");\n            throw new ServiceException(Status.TENANT_NOT_EXIST);\n        }\n        // Check the update tenant parameters\n        else if (StringUtils.isEmpty(updateTenant.getTenantCode())) {\n            throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, updateTenant.getTenantCode());","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TenantServiceImpl.java#L76-L112","documentation":"Status.OS_TENANT_CODE_EXIST from createTenantValid: a tenant with the given tenantCode already exists in t_ds_tenant (checkTenantExists returns true). Tenant codes are unique keys mapping to OS users, so duplicates are rejected.","triggerScenarios":"POST /tenants with a tenantCode that an earlier create already registered; createTenantIfNotExists races when two requests create the same tenant concurrently.","commonSituations":"Rerunning idempotency-broken bootstrap scripts; LDAP/SSO sync jobs running on multiple nodes simultaneously; admins recreating a tenant after a partially failed setup without checking existing tenants.","solutions":["Query the tenant list first and reuse the existing tenant instead of creating a new one.","Make scripts idempotent: check existence (or catch this error) before create.","Serialize tenant provisioning (single sync job, distributed lock) to avoid the create race.","If the old tenant is stale, delete it first via the tenant management API, then recreate."],"exampleFix":"// before\ntenantService.createTenant(loginUser, \"ds_tenant\", \"desc\", 1); // throws if exists\n// after\nif (!tenantService.checkTenantExists(\"ds_tenant\")) {\n    tenantService.createTenant(loginUser, \"ds_tenant\", \"desc\", 1);\n}","handlingStrategy":"try-catch","validationCode":"if (tenantService.checkTenantExists(tenantCode)) {\n    return; // tenant already provisioned\n}","typeGuard":null,"tryCatchPattern":"try {\n    tenantService.createTenant(loginUser, tenantCode, desc, queueId);\n} catch (ServiceException e) {\n    if (e.getCode() == 10009) { /* already exists: reuse it, don't fail the script */ }\n}","preventionTips":["Make bootstrap scripts idempotent (check-then-create or catch 10009)","Run tenant sync jobs on a single node or with a lock","List existing tenants before bulk provisioning","Don't blindly recreate tenants after failed setups"],"tags":["tenant","duplicate","uniqueness","api"],"backgroundTag":"file-already-exists","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}