AlistGo/alist · error

can not get captcha

Error message

can not get captcha

What it means

CloudreveV4 doLogin with captcha: GET /site/captcha returned a payload whose Image field does not start with 'data:image/png;base64,'. The driver cannot extract the base64 image to OCR it, so login aborts.

Source

Thrown at drivers/cloudreve_v4/util.go:145

		"email":    d.Username,
		"password": d.Password,
	}
	if needCaptcha {
		var config BasicConfigResp
		err = d.request(http.MethodGet, "/site/config/basic", nil, &config)
		if err != nil {
			return err
		}
		if config.CaptchaType != "normal" {
			return fmt.Errorf("captcha type %s not support", config.CaptchaType)
		}
		var captcha CaptchaResp
		err = d.request(http.MethodGet, "/site/captcha", nil, &captcha)
		if err != nil {
			return err
		}
		if !strings.HasPrefix(captcha.Image, "data:image/png;base64,") {
			return errors.New("can not get captcha")
		}
		loginBody["ticket"] = captcha.Ticket
		i := strings.Index(captcha.Image, ",")
		dec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(captcha.Image[i+1:]))
		vRes, err := base.RestyClient.R().SetMultipartField(
			"image", "validateCode.png", "image/png", dec).
			Post(setting.GetStr(conf.OcrApi))
		if err != nil {
			return err
		}
		if jsoniter.Get(vRes.Body(), "status").ToInt() != 200 {
			return errors.New("ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString())
		}
		captchaCode := jsoniter.Get(vRes.Body(), "result").ToString()
		if captchaCode == "" {
			return errors.New("ocr error: empty result")
		}
		loginBody["captcha"] = captchaCode

View on GitHub (pinned to 843d9dc814)

Solutions

  1. curl GET /site/captcha and inspect data.image — confirm it is a PNG data URL.
  2. Disable login captcha in Cloudrebve V4 admin settings to bypass the OCR path entirely.
  3. Align driver and server versions if the captcha format changed between releases.
  4. If the image is empty, address the server-side captcha generation failure first.

Example fix

curl -sS https://v4.example.com/api/v4/site/captcha
# good: {"code":0,"data":{"image":"data:image/png;base64,iVBOR...","ticket":"..."}}
# bad:  {"code":0,"data":{"image":"","ticket":"..."}}  -> fix server captcha or disable it
Defensive patterns

Strategy: validation

Validate before calling

if !strings.HasPrefix(captcha.Image, "data:image/png;base64,") {
    return errors.New("can not get captcha — server returned non-PNG or empty image")
}

Type guard

func isPngDataUrl(s string) bool {
    return strings.HasPrefix(s, "data:image/png;base64,") && len(s) > len("data:image/png;base64,")
}

Try / catch

if err := d.doLogin(true); err != nil {
    if err.Error() == "can not get captcha" {
        // inspect /site/captcha manually; disable captcha or fix server-side generation
        log.Printf("captcha payload malformed; got prefix %q", captcha.Image[:min(30, len(captcha.Image))])
    }
    return err
}

Prevention

When it happens

Trigger: config.CaptchaType == 'normal' (checked just above), the captcha request succeeds, but captcha.Image has an unexpected format — SVG data URL, JPEG prefix, empty string, or an error message in the field.

Common situations: Cloudrebve V4 instance configured with a non-PNG captcha renderer; version mismatch changing the data-URL mime; captcha endpoint returning an error object that unmarshals into Image as empty; proxy mangling the response.

Related errors


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