AlistGo/alist · critical

clientID and clientSecret are required in client_credentials

Error message

clientID and clientSecret are required in client_credentials mode

What it means

Returned by Terabox.Init when /api/check/login completes with errno != 0 and != 9000. In practice this means the configured cookie is invalid, expired, or lacks the required session fields, so the account cannot be authenticated.

Source

Thrown at drivers/123_open/client.go:38

// newSDKClient builds the SDK client for the configured authentication mode.
func (d *Open123) newSDKClient() (*pan123.Client, error) {
	opts := []pan123.Option{
		pan123.WithHTTPClient(&http.Client{Timeout: 60 * time.Second}),
		pan123.WithUserAgent("AList/" + conf.Version),
	}
	switch d.AuthMode {
	case AuthToken:
		if d.AccessToken == "" {
			return nil, errors.New("access_token is required in token mode")
		}
		c := pan123.NewWithToken(d.AccessToken, opts...)
		// expiry is unknown for an externally issued token; refresh on demand
		c.SetToken(d.AccessToken, d.tokenExpiry())
		return c, nil
	case AuthClientCredentials, "":
		if d.ClientID == "" || d.ClientSecret == "" {
			return nil, errors.New("clientID and clientSecret are required in client_credentials mode")
		}
		return pan123.New(d.ClientID, d.ClientSecret, opts...), nil
	default:
		return nil, fmt.Errorf("unknown auth_mode: %s", d.AuthMode)
	}
}

// tokenExpiry reports the stored expiry of an externally issued access token.
// A zero time tells the SDK never to refresh on its own; renewal is driven by
// ensureToken so the rotated refresh_token can be persisted.
func (d *Open123) tokenExpiry() time.Time {
	if d.accessTokenExpiredAt.IsZero() {
		return time.Time{}
	}
	return d.accessTokenExpiredAt
}

// ensureToken renews an externally issued access token when it is about to

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Re-log into Terabox in a browser and copy the complete, fresh cookie string into the driver configuration, then reload the storage.
  2. Confirm there is no leading/trailing whitespace or quote characters around the cookie value.
  3. If it still fails, clear cookies on the account, log in again, and re-add; check that the account itself is not restricted or banned.

Example fix

# before (config)
cookie: "lang=en; " # session cookies missing -> errno != 0

# after (config): full fresh cookie set from a live browser session
cookie: "ndus=...; jsToken=...; lang=en; ..."
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap pre-check: cookie has plausible required entries
if !strings.Contains(d.Cookie, "ndus=") {
	// cookie likely incomplete; re-copy from browser before Init
}

Type guard

func looksLikeTeraboxCookie(c string) bool {
	c = strings.TrimSpace(c)
	return c != "" && strings.Contains(c, "=") && !strings.HasPrefix(c, "\"")
}

Try / catch

if err := d.Init(ctx); err != nil {
	if strings.Contains(err.Error(), "failed to check login status") {
		// prompt user to refresh the cookie in storage config, then reload storage
	}
}

Prevention

When it happens

Trigger: Initializing or refreshing the Terabox storage with a Cookie value that is malformed, from a logged-out session, missing key cookies, or copied partially; changing the account password on the Terabox side invalidating the session.

Common situations: Cookie string copied without all entries or with stray characters/quotes; long-running mount whose cookie expired since last use; browser cookie rotation; account logged in elsewhere causing session invalidation.

Related errors


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