AlistGo/alist · error

generate totp code failed: %w

Error message

generate totp code failed: %w

What it means

During Mega driver Init, totp.GenerateCode failed on the configured TwoFACecret — the secret is not a valid base32 TOTP key, so no 6-digit code could be derived. This happens before any network login attempt; MultiFactorLogin is never reached. The %w wraps encoding/base32 or key-length errors from the TOTP library.

Source

Thrown at drivers/mega/driver.go:42

	Addition
	c *mega.Mega
}

func (d *Mega) Config() driver.Config {
	return config
}

func (d *Mega) GetAddition() driver.Additional {
	return &d.Addition
}

func (d *Mega) Init(ctx context.Context) error {
	var twoFACode = d.TwoFACode
	d.c = mega.New()
	if d.TwoFASecret != "" {
		code, err := totp.GenerateCode(d.TwoFASecret, time.Now())
		if err != nil {
			return fmt.Errorf("generate totp code failed: %w", err)
		}
		twoFACode = code
	}
	return d.c.MultiFactorLogin(d.Email, d.Password, twoFACode)
}

func (d *Mega) Drop(ctx context.Context) error {
	return nil
}

func (d *Mega) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
	if node, ok := dir.(*MegaNode); ok {
		nodes, err := d.c.FS.GetChildren(node.n)
		if err != nil {
			return nil, err
		}
		fn := make(map[string]model.Obj)
		for i := range nodes {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Re-copy the base32 secret exactly as Mega showed it (typically uppercase A-Z and 2-7, no separators) and strip whitespace/newlines
  2. If the secret came from an otpauth:// URL, use only the secret= parameter value, URL-decoded
  3. Verify the secret decodes: base32-decode it locally or with a TOTP test tool before configuring the driver
  4. If the account's 2FA was reset, regenerate and store the new secret; or clear TwoFASecret if 2FA is now disabled

Example fix

// before
code, err := totp.GenerateCode(d.TwoFASecret, time.Now())
if err != nil {
    return fmt.Errorf("generate totp code failed: %w", err)
}

// after
secret := strings.TrimSpace(strings.ToUpper(d.TwoFASecret))
secret = strings.ReplaceAll(secret, " ", "")
code, err := totp.GenerateCode(secret, time.Now())
if err != nil {
    return fmt.Errorf("generate totp code failed (secret must be base32): %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate base32 secret shape before Init
secret := strings.NewReplacer(" ", "", "\n", "", "-", "").Replace(strings.TrimSpace(d.TwoFASecret))
if secret != "" {
    if _, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(strings.ToUpper(secret)); err != nil {
        return fmt.Errorf("TwoFASecret is not valid base32: %w", err)
    }
}

Try / catch

// Surface the wrapped error verbatim; it names the base32 problem
if err := megaDriver.Init(ctx); err != nil {
    if strings.Contains(err.Error(), "totp") {
        // fix the stored secret, not the code
        return fmt.Errorf("invalid 2FA secret in storage config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: TwoFASecret set to the raw non-base32 string (e.g. copied from a URL's otpauth parameter without decoding); secret containing spaces, dashes, or lowercase characters that break strict base32; empty-after-trim secret; secret from a different scheme (hex) pasted by mistake.

Common situations: Users copying the 2FA secret shown during Mega account setup but including formatting; secrets exported from another authenticator in hex; trailing whitespace/newline from copy-paste into the driver config; secret regenerated on Mega's side so the stored value is stale.

Related errors


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