{"record":{"id":"2c8a3f8b8b5ffd0a","repo":"iflytek/astron-agent","slug":"s3-upload-error-2c8a3f","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/service/workflow/WorkflowArtifactService.java","lineNumber":317,"sourceCode":"        workflow = lockWorkflowForArtifactQuota(workflow.getId(), flowId, normalizedUid, spaceId);\n        enforceWorkflowArtifactQuota(workflow.getId(), file.getSize());\n        String objectKey = buildObjectKey(workflow.getId(), runId, validatedArtifact.fileName());\n        try (InputStream input = file.getInputStream()) {\n            s3ClientUtil.uploadObject(\n                    artifactProperties.getArtifactBucket(),\n                    objectKey,\n                    validatedArtifact.contentType(),\n                    input,\n                    file.getSize(),\n                    -1);\n        } catch (Exception ex) {\n            log.error(\n                    \"Upload workflow artifact failed, workflowId={}, uid={}, fileName={}\",\n                    workflow.getId(),\n                    normalizedUid,\n                    validatedArtifact.fileName(),\n                    ex);\n            throw new BusinessException(ResponseEnum.S3_UPLOAD_ERROR);\n        }\n        try {\n            WorkflowArtifact artifact = new WorkflowArtifact();\n            LocalDateTime now = LocalDateTime.now();\n            artifact.setUid(normalizedUid);\n            artifact.setSpaceId(workflow.getSpaceId());\n            artifact.setWorkflowId(workflow.getId());\n            artifact.setRunId(StringUtils.trimToEmpty(runId));\n            artifact.setNodeId(StringUtils.trimToEmpty(nodeId));\n            artifact.setSkillId(StringUtils.trimToEmpty(skillId));\n            artifact.setFileName(validatedArtifact.fileName());\n            artifact.setObjectKey(objectKey);\n            artifact.setBucketName(artifactProperties.getArtifactBucket());\n            artifact.setContentType(validatedArtifact.contentType());\n            artifact.setFileSize(file.getSize());\n            artifact.setSource(normalizeSource(source));\n            artifact.setDeleted(Boolean.FALSE);\n            artifact.setCreateTime(now);","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowArtifactService.java#L299-L335","documentation":"uploadInternal wraps any exception from the S3/object-storage put into S3_UPLOAD_ERROR. After the workflow and file are validated, the artifact bytes are written to object storage; if that call fails (network error, bad credentials, bucket missing, size/quota rejection), the service translates the low-level SDK exception into this BusinessException and logs workflowId, uid, and fileName for diagnosis.","triggerScenarios":"Object store unreachable or timing out during artifact upload; wrong S3 endpoint/credentials/bucket configuration; bucket quota or permission rejection; oversized multipart body dropped by a proxy before the SDK call.","commonSituations":"MinIO/S3 not running or misconfigured in the deployment environment; expired access keys; DNS or security-group changes breaking the storage endpoint; nginx client_max_body_size rejecting large artifacts.","solutions":["Check toolkit service logs for the wrapped 'Upload workflow artifact failed' stack trace to see the root SDK exception","Verify S3/MinIO connectivity and credentials (endpoint, access key, secret, bucket) in the service configuration","Confirm bucket exists and the service account has put-object permission; test with a direct SDK/mc upload","Check proxy/load-balancer body-size limits and request timeouts for large files"],"exampleFix":"// before: misconfigured endpoint -> S3_UPLOAD_ERROR\ns3.endpoint=http://internal-minio:9000  // host unreachable\n// after\ns3.endpoint=http://minio.minio.svc.cluster.local:9000\ns3.access-key=<valid-key>\ns3.secret-key=<valid-secret>","handlingStrategy":"retry","validationCode":"// Pre-flight the object store before uploading\nboolean ok = storageHealthCheck.ping(); // S3 headBucket or MinIO health endpoint\nif (!ok) throw new IllegalStateException(\"Object storage unreachable, abort upload\");","typeGuard":null,"tryCatchPattern":"try {\n    artifactApi.upload(workflowId, file);\n} catch (BusinessException e) {\n    if (\"S3_UPLOAD_ERROR\".equals(e.getCode())) {\n        log.error(\"S3 upload failed; check storage config/health\", e);\n        throw new StorageUnavailableException(e); // surface infra issue, don't blindly retry\n    }\n    throw e;\n}","preventionTips":["Health-check MinIO/S3 in deployment scripts before rolling out clients","Keep S3 credentials/endpoint in validated config; rotate keys before expiry","Set proxy body-size limits and timeouts above your max artifact size","Alert on 'Upload workflow artifact failed' log entries"],"tags":["java","s3","object-storage","upload","workflow-artifact"],"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"}