{"record":{"id":"0af8bfc76bdbd535","repo":"iflytek/astron-agent","slug":"s3-upload-error-0af8bf","errorCode":"S3_UPLOAD_ERROR","errorMessage":"S3_UPLOAD_ERROR","messagePattern":"S3_UPLOAD_ERROR","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/util/S3Util.java","lineNumber":131,"sourceCode":"            PutObjectArgs.Builder builder = PutObjectArgs.builder();\n            builder.bucket(bucketName);\n            builder.object(key);\n            builder.stream(input, objectSize, -1);\n            if (contentType != null && !contentType.isEmpty()) {\n                builder.contentType(contentType);\n            }\n            minioClient.putObject(builder.build());\n        } catch (ErrorResponseException\n                | InsufficientDataException\n                | InternalException\n                | InvalidKeyException\n                | InvalidResponseException\n                | IOException\n                | NoSuchAlgorithmException\n                | ServerException\n                | XmlParserException e) {\n            log.error(\"S3 putObject error: {}\", e.getMessage(), e);\n            throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR);\n        }\n    }\n\n    /**\n     * Upload an object of unknown size using multipart; {@code partSize} is required.\n     *\n     * @param key object key (path within the bucket)\n     * @param input input stream containing the object data (size unknown)\n     * @param contentType optional MIME type (e.g., {@code application/octet-stream}); may be null or\n     *        empty\n     * @param partSize multipart chunk size in bytes (recommended ≥ 5MB)\n     * @throws BusinessException when MinIO returns an error or any I/O/crypto error occurs\n     */\n    public void putObject(String key, InputStream input, String contentType, long partSize) {\n        try {\n            PutObjectArgs.Builder builder = PutObjectArgs.builder();\n            builder.bucket(bucketName);\n            builder.object(key);","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/util/S3Util.java#L113-L149","documentation":"S3_UPLOAD_ERROR is thrown by S3Util.putObject(key, input, objectSize, contentType) when the MinIO client putObject call fails with any of the wrapped MinIO/IO/crypto exceptions. The original exception is logged at error level, then converted into a BusinessException so callers only see the generic upload-failure response.","triggerScenarios":"minioClient.putObject(PutObjectArgs with bucket, object key, stream(input, objectSize, -1)) throws ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, or XmlParserException.","commonSituations":"Bucket does not exist or wrong s3.bucket config; access/secret key revoked or clock skew causing signature errors; S3/MinIO endpoint unreachable or network partition; object key contains illegal characters; declared objectSize mismatching actual stream data; bucket write policy denies the user.","solutions":["Check the server log for 'S3 putObject error' to see the underlying MinIO exception and error code (e.g. NoSuchBucket, AccessDenied)","Verify s3.endpoint, s3.accessKey, s3.secretKey and s3.bucket in the service configuration point to a reachable MinIO/S3 with an existing bucket","Confirm the credentials have write (s3:PutObject) permission on the bucket","Test connectivity to the S3 endpoint from the service host (network/firewall/DNS)","Ensure the passed objectSize equals the actual number of bytes available in the input stream, or use the unknown-size putObject variant with a partSize"],"exampleFix":"// before\nminioClient.putObject(builder.build()); // blind call, generic S3_UPLOAD_ERROR on failure\n// after\nif (objectSize <= 0) {\n    throw new IllegalArgumentException(\"objectSize must be positive for sized putObject\");\n}\ntry {\n    minioClient.putObject(builder.build());\n} catch (ErrorResponseException e) {\n    log.error(\"putObject failed: code={}, key={}\", e.errorResponse().code(), key, e);\n    throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR, e.errorResponse().code());\n}","handlingStrategy":"validation","validationCode":"// Validate config and args before calling putObject\nif (isBlank(s3Bucket)) throw new IllegalStateException(\"s3.bucket not configured\");\nif (key == null || key.isBlank()) throw new IllegalArgumentException(\"object key required\");\nif (objectSize <= 0) throw new IllegalArgumentException(\"objectSize must be positive\");\n// Optionally probe connectivity\ntry (var s = minioClient.listObjects(ListObjectsArgs.builder().bucket(s3Bucket).maxKeys(1).build()).iterator();) {\n    if (s.hasNext()) s.next();\n}","typeGuard":null,"tryCatchPattern":"try {\n    s3Util.putObject(key, input, size, contentType);\n} catch (BusinessException e) {\n    log.error(\"upload failed for key={}, check underlying 'S3 putObject error' log\", key, e);\n    throw e; // or return a typed failure to the caller\n}","preventionTips":["Verify bucket exists and credentials have PutObject permission during environment setup","Always pass an accurate objectSize matching the stream content","Add startup config validation for s3.endpoint/accessKey/secretKey/bucket","Check the error-level 'S3 putObject error' log for the exact MinIO error code"],"tags":["s3","minio","upload","storage"],"backgroundTag":"file-write-failed","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}