alibaba/nacos · error · NacosApiException

DATA_EMPTY

DATA_EMPTY

Error message

File is required

What it means

Thrown by validateAndExtractZipBytes when the uploaded MultipartFile is null or isEmpty() returns true. This is the entry-point validation for skill ZIP upload endpoints (both admin and console). The error uses ErrorCode.DATA_EMPTY with HTTP 400 to indicate no file was provided in the multipart request.

Source

Thrown at ai/src/main/java/com/alibaba/nacos/ai/utils/SkillRequestUtil.java:385

                ErrorCode.PARAMETER_VALIDATE_ERROR,
                "skillCard namespaceId must match request namespaceId");
        }
        skill.setNamespaceId(namespaceId);
    }
    
    /**
     * Validate uploaded skill zip file and extract bytes.
     *
     * <p>Validates the file is not null/empty, checks file size against the maximum limit,
     * and extracts the file bytes. This method is shared by both admin and console upload endpoints.</p>
     *
     * @param file the uploaded multipart file
     * @return the file bytes
     * @throws NacosException if validation fails or file reading fails
     */
    public static byte[] validateAndExtractZipBytes(MultipartFile file) throws NacosException {
        if (file == null || file.isEmpty()) {
            throw new NacosApiException(NacosException.INVALID_PARAM, ErrorCode.DATA_EMPTY,
                "File is required");
        }
        long maxUploadBytes = SkillZipParser.resolveMaxUploadBytes();
        if (file.getSize() > maxUploadBytes) {
            throw new NacosApiException(NacosException.INVALID_PARAM,
                ErrorCode.PARAMETER_VALIDATE_ERROR,
                "Skill zip size must not exceed "
                    + (maxUploadBytes / 1024 / 1024)
                    + "MB, current: " + (file.getSize() / 1024 / 1024) + "MB");
        }
        try {
            return file.getBytes();
        } catch (IOException e) {
            throw new NacosApiException(NacosException.SERVER_ERROR, ErrorCode.PARSING_DATA_FAILED,
                "Failed to read file: " + e.getMessage());
        }
    }
}

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Ensure the multipart form data includes a non-empty file part with the correct part name expected by the controller.
  2. Verify the file was actually selected and readable before form submission — add client-side validation for non-empty file selection.
  3. For curl testing, include the file argument: curl -F 'file=@skill.zip' ...
  4. Check that the Content-Type header is multipart/form-data and the file part name matches the @RequestParam("file") annotation.

Example fix

// before — curl command missing the file argument
curl -X POST http://localhost:8848/v3/admin/ai/skill/import?namespaceId=public

// after — file part included
curl -X POST -F 'file=@./skill.zip' http://localhost:8848/v3/admin/ai/skill/import?namespaceId=public
Defensive patterns

Strategy: validation

Validate before calling

// Check file is present and non-empty before upload
if (file == null || file.isEmpty()) {
    throw new IllegalArgumentException("A non-empty ZIP file is required");
}

Type guard

// JavaScript (frontend) type guard
function isValidFileUpload(file) {
    return file != null && file instanceof File && file.size > 0;
}

Try / catch

try {
    byte[] bytes = SkillRequestUtil.validateAndExtractZipBytes(file);
} catch (NacosApiException e) {
    if (ErrorCode.DATA_EMPTY.equals(e.getErrDetail())) {
        return ResponseEntity.badRequest().body("No file uploaded. Please select a ZIP file.");
    }
    throw e;
}

Prevention

When it happens

Trigger: POST to a skill upload/import endpoint (admin or console) where no file part is included in the multipart form data, or the file part is present but has zero bytes (empty file). The MultipartFile parameter resolves to null when the part name is wrong or absent.

Common situations: Frontend form does not include a file input or the file input is empty when the form is submitted; the multipart part name does not match the controller parameter name; curl command omits the -F file=@... argument; the file was selected but the browser failed to read it (permission denied locally).

Related errors


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