Tencent/WeKnora · error

failed to delete file from KS3: %w

Error message

failed to delete file from KS3: %w

What it means

ks3FileService.DeleteFile wraps DeleteObject SDK errors with "failed to delete file from KS3: %w". The key was valid but the remote delete failed — permissions, missing object (some configs), connectivity, or bucket mismatch. Note KS3/S3 DeleteObject often succeeds silently on missing keys, so this usually means permission or network trouble.

Source

Thrown at internal/application/service/file/ks3.go:251

	return resp.Body, nil
}

func (s *ks3FileService) DeleteFile(ctx context.Context, filePath string) error {
	_, objectKey, err := parseKS3FilePath(filePath)
	if err != nil {
		return err
	}
	if err := utils.SafeObjectKey(objectKey); err != nil {
		return fmt.Errorf("invalid file path: %w", err)
	}

	_, err = s.client.DeleteObject(&ks3s3.DeleteObjectInput{
		Bucket: ks3aws.String(s.bucketName),
		Key:    ks3aws.String(objectKey),
	})
	if err != nil {
		return fmt.Errorf("failed to delete file from KS3: %w", err)
	}
	return nil
}

func (s *ks3FileService) CheckConnectivity(ctx context.Context) error {
	done := make(chan error, 1)
	go func() {
		_, err := s.client.HeadBucket(&ks3s3.HeadBucketInput{
			Bucket: ks3aws.String(s.bucketName),
		})
		done <- err
	}()
	select {
	case <-ctx.Done():
		return ctx.Err()
	case err := <-done:
		return err
	}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check the wrapped error's code/status: 403 means grant DeleteObject (or s3:* on the prefix) to the configured AK/SK.
  2. Confirm bucket name in config matches the bucket encoded in stored ks3:// paths.
  3. For batch deletes, add retry/backoff around DeleteFile for 5xx/timeouts; SDK already retries 3 times.
  4. If the object is protected by a retention policy, remove the hold or delete via the console with admin rights.
  5. Treat 'delete failed but object actually gone' idempotently: verify with HeadObject before recreating records.

Example fix

// before
err := svc.DeleteFile(ctx, path) // fails with 403
// after
// attach a policy allowing DeleteObject on the prefix, then retry:
// {"Effect":"Allow","Action":"s3:DeleteObject","Resource":"arn:aws:s3:::bucket/prefix/*"}
err = svc.DeleteFile(ctx, path)
Defensive patterns

Strategy: retry

Validate before calling

// ensure object exists before delete if error must be meaningful
// (S3/KS3 DeleteObject is idempotent for missing keys)

Try / catch

err := svc.DeleteFile(ctx, path)
if err != nil {
	if strings.Contains(err.Error(), "403") {
		// fix credentials/policy, do not retry
	} else {
		// transient: retry with exponential backoff, max 3 attempts
	}
}

Prevention

When it happens

Trigger: DeleteObject returns an error: AK/SK lacks s3:DeleteObject permission, bucket in path differs from configured bucket, endpoint/region wrong, network failure after retries.

Common situations: Read-only credentials used for cleanup jobs; bucket policy changed to deny deletes; object under a retention/legal-hold-like policy; transient network outage during batch deletion.

Related errors


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