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 nilView on GitHub (pinned to 843d9dc814)
Solutions
- Log the exact wrapped SDK error and the normalized endpoint string to see which parameter oss.New rejected.
- Inspect normalizeOSSEndpoint's output for the failing token.EndPoint value and confirm it is a valid host (optionally with https:// scheme).
- Check whether the upload token's AccessKeyID/SecretAccessKey/SessionToken were populated from out.Data.Creds after the top-level fields came back empty.
- 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
- Validate endpoint and credential fields before calling oss.New so failures surface with clearer context.
- Treat upload tokens as short-lived: never cache them across long periods.
- Log the normalized endpoint on failure to distinguish provider changes from local config issues.
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.