Tencent/WeKnora · error
failed to upload file to OSS: %w
Error message
failed to upload file to OSS: %w
What it means
This error is returned by ossFileService.SaveFile when the simple (single-request) PutObject call to Alibaba Cloud OSS fails. It wraps the SDK error so callers can inspect the root cause. It is the non-multipart branch of SaveFile, used for smaller files or when the caller's reader fits a single request.
Source
Thrown at internal/application/service/file/oss.go:210
&oss.PutObjectRequest{
Bucket: oss.Ptr(s.bucketName),
Key: oss.Ptr(objectName),
ContentType: oss.Ptr(contentType),
},
src,
)
if err != nil {
return "", fmt.Errorf("failed to upload file to OSS (multipart): %w", err)
}
} else {
_, err = s.client.PutObject(ctx, &oss.PutObjectRequest{
Bucket: oss.Ptr(s.bucketName),
Key: oss.Ptr(objectName),
Body: src,
ContentType: oss.Ptr(contentType),
})
if err != nil {
return "", fmt.Errorf("failed to upload file to OSS: %w", err)
}
}
return fmt.Sprintf("oss://%s/%s", s.bucketName, objectName), nil
}
// SaveBytes saves bytes data to OSS.
// If temp is true and temp bucket is configured, saves to temp bucket.
// Otherwise saves to main bucket.
func (s *ossFileService) SaveBytes(ctx context.Context, data []byte, tenantID uint64, fileName string, temp bool) (string, error) {
safeName, err := utils.SafeFileName(fileName)
if err != nil {
return "", fmt.Errorf("invalid file name: %w", err)
}
ext := filepath.Ext(safeName)
targetBucket := s.bucketName
client := s.clientView on GitHub (pinned to 988cbb0330)
Solutions
- Unwrap the error to read the OSS error code (e.g., AccessDenied, NoSuchBucket, SignatureDoesNotMatch).
- Validate s.bucketName and endpoint configuration match the actual bucket region.
- Verify RAM policy grants oss:PutObject on the target key prefix.
- Confirm credentials/STS tokens are current.
- Check that src is readable and not already consumed (a drained reader causes body errors).
Example fix
// before
_, err = s.client.PutObject(ctx, &oss.PutObjectRequest{...})
if err != nil {
return "", fmt.Errorf("failed to upload file to OSS: %w", err)
}
// after
if err != nil {
logger.Errorf(ctx, "OSS PutObject failed bucket=%s key=%s: %v", s.bucketName, objectName, err)
return "", fmt.Errorf("failed to upload file to OSS: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if s.bucketName == "" { return errors.New("OSS bucket not configured") }
if fi, err := os.Stat(localPath); err != nil || fi.Size() == 0 { return fmt.Errorf("source unreadable: %w", err) } Try / catch
path, err := svc.SaveFile(ctx, src, tenantID, name, ctype, false)
var svcErr *oss.ServiceError
if errors.As(err, &svcErr) {
switch svcErr.Code {
case "AccessDenied": // fix RAM permissions
case "NoSuchBucket": // fix bucket config
case "SignatureDoesNotMatch": // fix credentials
}
} Prevention
- Keep bucket name and endpoint region consistent in configuration.
- Rotate and test credentials before expiry.
- Ensure the src reader is fresh and not already consumed.
- Grant oss:PutObject to the service role on the target prefix.
- Log the unwrapped OSS error code for fast diagnosis.
When it happens
Trigger: Calling SaveFile with content under the multipart threshold and client.PutObject fails: invalid credentials, bucket does not exist, no PutObject permission, request body read error from src, or network failure before/during the PUT.
Common situations: Misconfigured bucket name in config/env; OSS endpoint region mismatch (bucket in cn-hangzhou, client pointed at another region); antivirus/permission tools locking the source file; SDK credentials expired (signature-time errors).
Related errors
- failed to upload file to OSS (multipart): %w
- failed to upload bytes to OSS: %w
- failed to upload file to OBS: %w
- failed to copy file in OSS: %w
- failed to get file from OSS: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/63e40aa11e86b03f.
Report an issue: GitHub.