AlistGo/alist · error
yunpan auth failed: errno=%d
Error message
yunpan auth failed: errno=%d
What it means
Thrown by Yunnan 360 Yunpan (yunpan360) driver's getOpenAuth when the Oauth.getAccessTokenByApiKey call returns a non-zero errno and the server supplied no errmsg text. The driver exchanges the configured APIKey (plus client_id/client_secret and sub_channel) for an access token at openAPIURL(d.EcsEnv); any non-zero errno aborts authentication before caching OpenAuthInfo, so every subsequent openAPI operation fails.
Source
Thrown at drivers/yunpan360/util.go:211
"client_id": openClientID,
"client_secret": openClientSecretForEnv(d.EcsEnv),
"grant_type": "authorization_code",
"sub_channel": d.SubChannel,
"api_key": d.APIKey,
})
res, err := req.Get(reqURL)
if err != nil {
return nil, err
}
var resp OpenAuthResp
if err := utils.Json.Unmarshal(res.Body(), &resp); err != nil {
return nil, err
}
if resp.Errno != 0 {
if resp.Errmsg == "" {
return nil, fmt.Errorf("yunpan auth failed: errno=%d", resp.Errno)
}
return nil, errors.New(resp.Errmsg)
}
auth := &OpenAuthInfo{
AccessToken: resp.Data.AccessToken,
Qid: resp.Data.Qid,
Token: resp.Data.Token,
SubChannel: d.SubChannel,
}
d.cachedOpenAuth = auth
d.openAuthExpire = time.Now().Add(50 * time.Minute)
copied := *auth
return &copied, nil
}
func (d *Yunpan360) openBaseParams(auth *OpenAuthInfo, method string, signParams map[string]string, withSign bool) map[string]string {View on GitHub (pinned to 843d9dc814)
Solutions
- Verify the APIKey configured for the yunpan360 storage is valid and not revoked on 360's open platform
- Check that EcsEnv matches the environment the key was issued for (openAPIURL picks the endpoint from it)
- Confirm sub_channel is one allowed for the app; try the value the key was provisioned with
- Test the token exchange manually with method=Oauth.getAccessTokenByApiKey and the same client_id/client_secret to see the raw errno
- Map the errno against 360 open-platform error tables; if the key is revoked, issue a new one and update the driver config
Example fix
// before: invalid/mismatched config
driver := Yunpan360{APIKey: "old-key", EcsEnv: "", SubChannel: "wrong"}
// after: key, env and channel consistent with the 360 open-platform app
driver := Yunpan360{APIKey: validKey, EcsEnv: provisionedEnv, SubChannel: "web"} Defensive patterns
Strategy: retry
Validate before calling
// Before mounting/first use, probe credentials with the same exchange the driver performs
func probeYunpanAuth(ctx context.Context, apiKey, ecsEnv, subChannel string) error {
q := url.Values{}
q.Set("method", "Oauth.getAccessTokenByApiKey")
q.Set("api_key", apiKey)
q.Set("sub_channel", subChannel)
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, openAPIURL(ecsEnv)+"?"+q.Encode(), nil)
resp, err := http.DefaultClient.Do(req)
if err != nil { return err }
defer resp.Body.Close()
var r struct{ Errno int `json:"errno"`; Errmsg string `json:"errmsg"` }
if err := json.NewDecoder(resp.Body).Decode(&r); err != nil { return err }
if r.Errno != 0 { return fmt.Errorf("auth probe errno=%d msg=%q", r.Errno, r.Errmsg) }
return nil
} Try / catch
// Go: treat as terminal config error; do not blind-retry auth with the same key
if err := d.getOpenAuth(ctx); err != nil {
if strings.Contains(err.Error(), "yunpan auth failed") {
// credential/config problem: surface to user, stop retrying
return fmt.Errorf("yunpan360 credentials rejected: %w", err)
}
return err // transport error: retryable
} Prevention
- Validate the API key and EcsEnv with a probe call when configuring the storage, not at first file operation
- Monitor auth failures after the 50-minute cache expiry to catch mid-session revocation early
- Keep sub_channel consistent with the value the 360 app was provisioned for
When it happens
Trigger: Calling any yunpan360 operation that needs the open API (openGET/openPOST -> getOpenAuth) while the api_key is invalid/revoked, the EcsEnv selects the wrong endpoint, the sub_channel is not permitted, or 360's open platform rejects the credentials with an errno-only response (empty errmsg field).
Common situations: Expired or mistyped API key in the storage config; EcsEnv mismatch (production vs ECS endpoint); 360 open-platform app disabled or quota exhausted; token cache expired after 50 minutes and re-auth is rejected; upstream API contract change dropping errmsg.
Related errors
- api_key is empty
- cookie is empty
- invalid auth_type
- baseResp.Errmsg
- failed to refresh token: refresh token is empty
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/925a1139421418f8.
Report an issue: GitHub.