alibaba/nacos · error · NacosApiException

ACCESS_DENIED

ACCESS_DENIED

Error message

{errMsg}, owner: {owner}

What it means

An ACCESS_DENIED (HTTP 403, ErrorCode ACCESS_DENIED/10001) from checkWritableUploadResource: VisibilityHelper.checkWritableResource already rejected the write (NO_RIGHT), and the resource meta carries an owner, so the original message is enriched with ', owner: <owner>' to tell the caller who controls the resource. It is an authorization failure, not a validation error.

Source

Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/skills/SkillOperationServiceImpl.java:418

            return overwriteUploadedSkill(namespaceId, skill, targetVersion, meta, true,
                commitMsg);
        }
        if (SkillUploadPrecheckResult.ACTION_DELETE_DRAFT_AND_CREATE.equals(uploadAction)) {
            return overwriteUploadedSkill(namespaceId, skill, targetVersion, meta, true,
                commitMsg);
        }
        throw new NacosApiException(NacosException.INVALID_PARAM,
            ErrorCode.PARAMETER_VALIDATE_ERROR, "Unsupported uploadAction: " + uploadAction);
    }
    
    private void checkWritableUploadResource(AiResource meta) throws NacosException {
        try {
            VisibilityHelper.checkWritableResource(meta);
        } catch (NacosException e) {
            if (e.getErrCode() != NacosException.NO_RIGHT || StringUtils.isBlank(meta.getOwner())) {
                throw e;
            }
            throw new NacosApiException(NacosException.NO_RIGHT, ErrorCode.ACCESS_DENIED,
                e.getErrMsg() + ", owner: " + meta.getOwner());
        }
    }
    
    /**
     * Bootstrap a built-in skill from a ZIP archive (delegates to the overload with null source).
     */
    @Override
    public void bootstrapSkillFromZip(String namespaceId, byte[] zipBytes) throws NacosException {
        bootstrapSkillFromZip(namespaceId, zipBytes, null);
    }
    
    /**
     * Bootstrap a built-in skill from a ZIP archive. Skips if the skill already exists.
     *
     * <p>Unlike upload, this directly writes storage and creates a published meta + version
     * in one step (no draft/review workflow), and also initializes the index manifest.</p>
     */

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Contact the listed owner (or an admin) to make the change or transfer ownership.
  2. Authenticate as a user/role that has write permission on the resource.
  3. Use precheckUploadSkillFromZip first — it returns PRECHECK_CODE_NO_PERMISSION without attempting the write.
Defensive patterns

Strategy: try-catch

Validate before calling

// Fetch meta and compare owner/identity before attempting a write upload.
AiResource meta = resourceManager.findMeta(ns, name, RESOURCE_TYPE_SKILL);
if (meta != null && !isWriter(meta.getOwner())) {
    // surface 'owned by <owner>' to the user instead of attempting the upload
}

Try / catch

try {
    skillOp.uploadSkillFromZip(req);
} catch (NacosApiException e) {
    if (e.getErrCode() == NacosException.NO_RIGHT
            && ErrorCode.ACCESS_DENIED.getCode() == e.getDetailErrCode()) {
        // tell the user who the owner is and that they need permission/transfer
        showOwnerGuidance(e.getErrMsg());
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Uploading or overwriting a skill whose meta exists and is owned by another user/identity when the current caller is neither the owner nor an administrator with write permission.

Common situations: Shared namespace where a colleague owns the skill; logged in as the wrong user/service account; role lacks the write permission for that resource scope.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/7cd2d2347466d999. Report an issue: GitHub.