AlistGo/alist · error
ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString()
Error message
ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString()
What it means
Raised after the captcha image was forwarded to the configured OCR HTTP service (setting conf.OcrApi, posted as multipart field 'image') and that service answered with a JSON body whose status is not 200. The OCR service's own msg field is appended, e.g. 'ocr error:model not loaded'.
Source
Thrown at drivers/cloudreve/util.go:138
if needCaptcha {
var captcha string
err = d.request(http.MethodGet, "/site/captcha", nil, &captcha)
if err != nil {
return err
}
if len(captcha) == 0 {
return errors.New("can not get captcha")
}
i := strings.Index(captcha, ",")
dec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(captcha[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()
}
var resp Resp
err = d.request(http.MethodPost, loginPath, func(req *resty.Request) {
req.SetBody(base.Json{
"username": d.Addition.Username,
"Password": d.Addition.Password,
"captchaCode": captchaCode,
})
}, &resp)
return err
}
func convertSrc(obj model.Obj) map[string]interface{} {
m := make(map[string]interface{})
var dirs []string
var items []stringView on GitHub (pinned to 843d9dc814)
Solutions
- Set the OcrApi setting to a working OCR service (e.g. a deployed ddddocr API: https://github.com/sml2h3/ddddocr) and test it with a manual multipart POST of a PNG.
- Check the OCR service logs — its msg field names the exact failure (model missing, decode error).
- Disable login captcha on the Cloudrebve side so no OCR is needed.
- Ensure the URL in OcrApi is the full endpoint (scheme+host+path) and reachable from the alist/OpenList host.
Example fix
# before: placeholder OCR api PUT /api/setting/ocr_api -> "" # after: working ddddocr service PUT /api/setting/ocr_api -> "http://127.0.0.1:9898"
Defensive patterns
Strategy: validation
Validate before calling
// health-check the OCR service before relying on it during login
if setting.GetStr(conf.OcrApi) == "" {
return errors.New("OcrApi not configured; cannot solve login captcha")
}
if resp, err := http.Get(setting.GetStr(conf.OcrApi) + "/ping"); err != nil || resp.StatusCode != 200 {
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:") {
// captcha/OCR path failed: fix OcrApi or disable captcha rather than retrying blindly
log.Printf("ocr login failed: %s; check conf.OcrApi service", err)
}
return err
} Prevention
- Deploy and health-check a ddddocr-style OCR service before enabling captcha logins
- Set conf.OcrApi to a tested full URL
- Disable captcha on the Cloudrebve side when headless mounting
When it happens
Trigger: doLogin with captcha enabled: image POSTed to setting.GetStr(conf.OcrApi); response body parsed with jsoniter and status != 200. Happens when the OCR endpoint is misconfigured, down, returns HTML (proxy error page), or the ddddocr-style service fails to recognize/load.
Common situations: conf.OcrApi left pointing at default/placeholder URL; OCR container not running or crashing on the PNG; reverse proxy in front of the OCR service returning 502 HTML so status parses to 0; OCR service version that expects a different field name than 'image'.
Related errors
- ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString()
- can not get captcha
- ocr error: empty result
- r.Msg
- res.Status
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/4ba469d57bc2080f.
Report an issue: GitHub.