AlistGo/alist · error

create oss client failed: %w

Error message

create oss client failed: %w

What it means

Thrown when aliyun-oss-go-sdk's oss.New() rejects the parameters used to build an OSS client for a GuangYaPan upload: the endpoint URL, AccessKeyID, SecretAccessKey, or STS SecurityToken derived from the upload token. oss.New only parses and validates the endpoint/credential strings locally, so a failure here means malformed data, not a network problem. The %w chain preserves the SDK's underlying reason (most often a malformed endpoint URL after normalizeOSSEndpoint).

Source

Thrown at drivers/guangyapan/driver.go:413

	if err != nil {
		return err
	}
	taskID := strings.TrimSpace(token.TaskID)
	if code == 156 {
		if taskID == "" {
			return errors.New("instant upload returns empty task id")
		}
		return d.waitUploadTaskInfo(ctx, taskID)
	}

	if token.ObjectPath == "" || token.BucketName == "" || token.EndPoint == "" || token.AccessKeyID == "" || token.SecretAccessKey == "" {
		return errors.New("upload token is incomplete")
	}

	ossEndpoint := normalizeOSSEndpoint(token.EndPoint, token.BucketName)
	client, err := oss.New(ossEndpoint, token.AccessKeyID, token.SecretAccessKey, oss.SecurityToken(token.SessionToken))
	if err != nil {
		return fmt.Errorf("create oss client failed: %w", err)
	}
	bucket, err := client.Bucket(token.BucketName)
	if err != nil {
		return fmt.Errorf("create oss bucket failed: %w", err)
	}

	if file.GetSize() == 0 {
		if err := bucket.PutObject(token.ObjectPath, strings.NewReader("")); err != nil {
			return err
		}
	} else {
		if err := d.multipartUploadToOSS(ctx, bucket, token.ObjectPath, file, up); err != nil {
			return err
		}
	}

	if taskID == "" {
		return nil

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Log the exact wrapped SDK error and the normalized endpoint string to see which parameter oss.New rejected.
  2. Inspect normalizeOSSEndpoint's output for the failing token.EndPoint value and confirm it is a valid host (optionally with https:// scheme).
  3. Check whether the upload token's AccessKeyID/SecretAccessKey/SessionToken were populated from out.Data.Creds after the top-level fields came back empty.
  4. If the provider changed the token payload shape, update uploadTokenData/getUploadToken parsing to match the current API response.

Example fix

// before
ossEndpoint := normalizeOSSEndpoint(token.EndPoint, token.BucketName)
client, err := oss.New(ossEndpoint, token.AccessKeyID, token.SecretAccessKey, oss.SecurityToken(token.SessionToken))
if err != nil {
    return fmt.Errorf("create oss client failed: %w", err)
}

// after - include endpoint in the error for diagnosis
ossEndpoint := normalizeOSSEndpoint(token.EndPoint, token.BucketName)
client, err := oss.New(ossEndpoint, token.AccessKeyID, token.SecretAccessKey, oss.SecurityToken(token.SessionToken))
if err != nil {
    return fmt.Errorf("create oss client failed (endpoint=%s): %w", ossEndpoint, err)
}
Defensive patterns

Strategy: validation

Validate before calling

// before building the OSS client, sanity-check the token fields
if u, err := url.Parse(token.EndPoint); err != nil || u.Host == "" {
    return fmt.Errorf("upload token endpoint invalid: %q", token.EndPoint)
}
if token.AccessKeyID == "" || token.SecretAccessKey == "" {
    return errors.New("upload token credentials missing")
}

Try / catch

if err := d.Put(ctx, dstDir, file, overwrite); err != nil {
    if strings.Contains(err.Error(), "create oss client failed") {
        // token/endpoint problem: drop cached upload token and let the next attempt fetch a fresh one
        log.Warnf("oss client creation failed, will re-request upload token: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Put() reaches the direct-OSS branch after the upload token passes the completeness check (token.EndPoint/BucketName/AccessKeyID/SecretAccessKey all non-empty), and oss.New(normalizeOSSEndpoint(token.EndPoint, token.BucketName), ...) fails to parse the constructed endpoint (bad scheme, unparseable host) or the credential strings.

Common situations: GuangYaPan's get_res_center_token API changed its endpoint format (adds scheme or path unexpectedly); a proxy or region rewrite mangles the endpoint; the STS credentials field layout changed so creds fall back to empty/odd values.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/a4d2b0f9e98bf35d. Report an issue: GitHub.