Tencent/WeKnora · error

failed to upload bytes to OBS: %w

Error message

failed to upload bytes to OBS: %w

What it means

OBS PutObject failed while uploading the in-memory byte payload (public-read ACL, temp or tenant-prefixed key) to OBS, so the bytes were not persisted; permissions, quota, or connectivity causes are wrapped in the error.

Source

Thrown at internal/application/service/file/obs.go:316

			objectKey = fmt.Sprintf("temp/%d/%s%s", tenantID, uuid.New().String(), ext)
		}
	} else {
		if s.pathPrefix != "" {
			objectKey = fmt.Sprintf("%s/%d/%s%s", s.pathPrefix, tenantID, uuid.New().String(), ext)
		} else {
			objectKey = fmt.Sprintf("%d/%s%s", tenantID, uuid.New().String(), ext)
		}
	}

	_, err := s.client.PutObject(ctx, &s3.PutObjectInput{
		Bucket:      aws.String(s.bucketName),
		Key:         aws.String(objectKey),
		Body:        strings.NewReader(string(data)),
		ContentType: aws.String("application/octet-stream"),
		ACL:         "public-read",
	})
	if err != nil {
		return "", fmt.Errorf("failed to upload bytes to OBS: %w", err)
	}

	prefix := s.getPrifix()
	if s.proxyDomain != "" {
		return fmt.Sprintf("%s%s", prefix, objectKey), nil
	}
	return fmt.Sprintf("%s%s/%s", prefix, s.bucketName, objectKey), nil
}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Unwrap the error: if it mentions ACL, the bucket has ACLs disabled (BucketOwnerEnforced) — remove the ACL: "public-read" field or enable ACLs
  2. Verify credentials, endpoint, region and bucketName config
  3. Check the credentials have s3:PutObject on the target prefix
  4. Retry transient network errors with backoff; the objectKey is deterministic per call so retries are safe

Example fix

// before
if err != nil { return "", fmt.Errorf("failed to upload bytes to OBS: %w", err) }
// after
if err != nil {
    if strings.Contains(err.Error(), "ACL") || strings.Contains(err.Error(), "AccessControlListNotSupported") {
        // retry without ACL
        return s.putBytesWithoutACL(ctx, objectKey, data)
    }
    return "", fmt.Errorf("failed to upload bytes to OBS: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

if len(data) == 0 { return errors.New("nothing to upload") }
if bucketName == "" || endpoint == "" { return errors.New("OSS/OBS config incomplete") }

Try / catch

path, err := svc.SaveBytes(ctx, tenantID, kid, data)
if err != nil {
    if isRetryableNetErr(err) {
        path, err = svc.SaveBytes(ctx, tenantID, kid, data)
    }
    if err != nil {
        return fmt.Errorf("obs bytes upload failed: %w", err)
    }
}

Prevention

When it happens

Trigger: PutObject with Body=strings.NewReader(data) fails on network errors, invalid credentials, missing PutObject permission, bucket not existing, or payload too large for available memory/network stability.

Common situations: AK/SK rotated but config not updated; bucket policy denying public-read ACL (ObjectOwnership ACLs disabled → ACL not permitted); endpoint/region misconfig; transient network drop.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/ec9fe476d2d7bc8c. Report an issue: GitHub.