{"record":{"id":"e4dc5639758e3583","repo":"alibaba/nacos","slug":"parsing-data-failed-e4dc56","errorCode":"PARSING_DATA_FAILED","errorMessage":"Failed to read file: ${e.getMessage()}","messagePattern":"Failed to read file: (.+?)","errorType":"exception","errorClass":"NacosApiException","httpStatus":500,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/utils/SkillRequestUtil.java","lineNumber":399,"sourceCode":"     * @throws NacosException if validation fails or file reading fails\n     */\n    public static byte[] validateAndExtractZipBytes(MultipartFile file) throws NacosException {\n        if (file == null || file.isEmpty()) {\n            throw new NacosApiException(NacosException.INVALID_PARAM, ErrorCode.DATA_EMPTY,\n                \"File is required\");\n        }\n        long maxUploadBytes = SkillZipParser.resolveMaxUploadBytes();\n        if (file.getSize() > maxUploadBytes) {\n            throw new NacosApiException(NacosException.INVALID_PARAM,\n                ErrorCode.PARAMETER_VALIDATE_ERROR,\n                \"Skill zip size must not exceed \"\n                    + (maxUploadBytes / 1024 / 1024)\n                    + \"MB, current: \" + (file.getSize() / 1024 / 1024) + \"MB\");\n        }\n        try {\n            return file.getBytes();\n        } catch (IOException e) {\n            throw new NacosApiException(NacosException.SERVER_ERROR, ErrorCode.PARSING_DATA_FAILED,\n                \"Failed to read file: \" + e.getMessage());\n        }\n    }\n}\n","sourceCodeStart":381,"sourceCodeEnd":404,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/utils/SkillRequestUtil.java#L381-L404","documentation":"Thrown by validateAndExtractZipBytes when MultipartFile.getBytes() throws an IOException. This is a server-side I/O failure during the read of an otherwise-valid uploaded file — the file passed null/empty and size checks but could not be fully read into memory.","triggerScenarios":"POST to a skill upload endpoint where the file passes initial validation (non-null, non-empty, within size limit) but a transient I/O error occurs when reading the file bytes into memory. Causes include temporary file cleanup by the OS, disk read errors, or the client disconnecting mid-upload causing the multipart temp file to become unreadable.","commonSituations":"Client disconnects during multipart upload leaving a truncated temp file; the server's temp directory runs out of disk space mid-upload; the multipart temp file is cleaned up by another process beforegetBytes() is called; a disk I/O error on the server's storage.","solutions":["Retry the upload — transient I/O errors often resolve on the second attempt.","Check server disk space in the temp directory (java.io.tmpdir) and ensure it has headroom for multipart uploads.","If using a reverse proxy (nginx, etc.), verify proxy_read_timeout and client_body_timeout are long enough for large uploads.","If the error persists, inspect the server's disk health and the multipart configuration (spring.servlet.multipart.location for temp file storage)."],"exampleFix":"// before — caller has no retry logic\nbyte[] bytes = SkillRequestUtil.validateAndExtractZipBytes(file);\n\n// after — retry on transient IOException with a guard\nbyte[] bytes;\nint maxRetries = 3;\nfor (int attempt = 1; attempt <= maxRetries; attempt++) {\n    try {\n        bytes = SkillRequestUtil.validateAndExtractZipBytes(file);\n        break;\n    } catch (NacosApiException e) {\n        if (!ErrorCode.PARSING_DATA_FAILED.equals(e.getErrDetail())\n            || attempt == maxRetries) {\n            throw e;\n        }\n    }\n}","handlingStrategy":"retry","validationCode":"// Verify file is readable before calling validateAndExtractZipBytes\ntry {\n    if (file == null || file.isEmpty()) {\n        throw new IllegalArgumentException(\"File is empty\");\n    }\n    // Proactive read check is not possible without consuming the stream,\n    // so rely on retry for transient I/O errors.\n} catch (Exception e) {\n    log.warn(\"File pre-check failed\", e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    byte[] bytes = SkillRequestUtil.validateAndExtractZipBytes(file);\n} catch (NacosApiException e) {\n    if (ErrorCode.PARSING_DATA_FAILED.equals(e.getErrDetail())) {\n        log.warn(\"Transient I/O error reading uploaded file, retrying...\", e);\n        // For HTTP uploads, instruct the client to re-upload\n        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)\n            .body(\"Failed to read file. Please retry the upload.\");\n    }\n    throw e;\n}","preventionTips":["Ensure the server temp directory has sufficient free disk space for multipart uploads.","Set appropriate proxy timeouts (proxy_read_timeout) if behind a reverse proxy.","Monitor disk space and I/O health on the server.","For programmatic callers, implement retry with exponential backoff for IOException-based failures."],"tags":["skill","file-upload","io-error","transient"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}