AlistGo/alist · error
ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString()
Error message
ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString()
What it means
CloudreveV4 login forwarded the captcha PNG to the configured OCR service (conf.OcrApi multipart field 'image') and the service answered with a non-200 status in its JSON body; its msg is appended, e.g. 'ocr error:internal error'. Identical pattern to the V3 driver's OCR failure.
Source
Thrown at drivers/cloudreve_v4/util.go:157
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
}
var token TokenResponse
err = d.request(http.MethodPost, "/session/token", func(req *resty.Request) {
req.SetBody(loginBody)
}, &token)
if err != nil {
return err
}
d.AccessToken, d.RefreshToken = token.Token.AccessToken, token.Token.RefreshToken
op.MustSaveDriverStorage(d)
return nil
}View on GitHub (pinned to 843d9dc814)
Solutions
- Configure OcrApi to a reachable OCR service and test it manually with a multipart PNG upload.
- Read the OCR service's msg in the error to pinpoint its failure.
- Disable captcha on the V4 site to remove the dependency.
- Ensure network/DNS from the alist host to the OCR service works.
Example fix
curl -sS -F 'image=@validateCode.png;type=image/png' http://127.0.0.1:9898
# {"status":200,"result":"ab12"} -> OCR service healthy; set this URL as OcrApi Defensive patterns
Strategy: validation
Validate before calling
if setting.GetStr(conf.OcrApi) == "" { return errors.New("configure OcrApi before enabling captcha login") }
if _, err := http.Head(setting.GetStr(conf.OcrApi)); err != nil { return errors.New("OCR service unreachable") } Type guard
func isOcrError(err error) bool { return err != nil && strings.HasPrefix(err.Error(), "ocr error:") } Try / catch
if err != nil {
if strings.HasPrefix(err.Error(), "ocr error:") {
return fmt.Errorf("captcha OCR failed (%s) — fix/disable OcrApi or turn off captcha", err)
}
return err
} Prevention
- Deploy a tested OCR service before enabling captcha
- Log the OCR service msg to catch config drift
- Prefer disabling captcha for API-driven logins
When it happens
Trigger: Captcha enabled + OCR POST to setting.GetStr(conf.OcrApi); response body's status field != 200. Triggered by missing/wrong OcrApi setting, dead OCR service, HTML proxy error page (status parses to 0), or OCR decode failure.
Common situations: OcrApi never configured after enabling captcha; ddddocr container down; URL typo; service expecting a different multipart field name; network egress blocked from the alist host.
Related errors
- ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString()
- ocr error: empty result
- resp.String()
- authn not support
- can not get captcha
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/883a6cb6f56ee0d6.
Report an issue: GitHub.