AlistGo/alist · warning

markdown conversion failed: %w

Error message

markdown conversion failed: %w

What it means

When serving a markdown file preview, the proxied file bytes are converted to HTML with goldmark (GFM extensions) and sanitized with bluemonday. If goldmark's Convert returns an error, it is wrapped as 'markdown conversion failed: %w'.

Source

Thrown at server/handles/down.go:157

		common.ProxyRange(link, file.GetSize())
	}
	Writer := &common.WrittenResponseWriter{ResponseWriter: c.Writer}

	//优先处理md文件
	if utils.Ext(file.GetName()) == "md" && setting.GetBool(conf.FilterReadMeScripts) {
		buf := bytes.NewBuffer(make([]byte, 0, file.GetSize()))
		w := &common.InterceptResponseWriter{ResponseWriter: Writer, Writer: buf}
		err = common.Proxy(w, c.Request, link, file)
		if err == nil && buf.Len() > 0 {
			if c.Writer.Status() < 200 || c.Writer.Status() > 300 {
				c.Writer.Write(buf.Bytes())
				return
			}

			var html bytes.Buffer
			md := goldmark.New(goldmark.WithExtensions(extension.GFM))
			if err = md.Convert(buf.Bytes(), &html); err != nil {
				err = fmt.Errorf("markdown conversion failed: %w", err)
			} else {
				buf.Reset()
				err = bluemonday.UGCPolicy().SanitizeReaderToWriter(&html, buf)
				if err == nil {
					Writer.Header().Set("Content-Length", strconv.FormatInt(int64(buf.Len()), 10))
					Writer.Header().Set("Content-Type", "text/html; charset=utf-8")
					_, err = utils.CopyWithBuffer(Writer, buf)
				}
			}
		}
	} else {
		err = common.Proxy(Writer, c.Request, link, file)
	}
	if err == nil {
		return
	}
	if Writer.IsWritten() {
		log.Errorf("%s %s local proxy error: %+v", c.Request.Method, c.Request.URL.Path, err)

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Check the wrapped error for the precise goldmark failure
  2. Try downloading the raw file instead of preview to confirm content serves fine
  3. Shrink/split pathological markdown files (huge single-line base64 images are a common culprit)
  4. Upgrade AList to pick up a newer goldmark if a parser bug is confirmed
Defensive patterns

Strategy: try-catch

Validate before calling

if file.GetSize() > maxMarkdownPreviewSize {
    // serve raw download instead of conversion
    return common.Proxy(w, c.Request, link, file)
}

Try / catch

if err = md.Convert(buf.Bytes(), &html); err != nil {
    // fall back to serving the raw markdown text rather than a 500
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    _, _ = w.Write(buf.Bytes())
}

Prevention

When it happens

Trigger: Requesting the rendered preview of a .md file whose content triggers a goldmark parse failure — in practice rare, since goldmark is fault-tolerant; realistic causes are writer errors from the bytes.Buffer or memory pressure on very large files.

Common situations: Extremely large markdown files exhausting memory; edge-case content hitting a goldmark bug in the pinned version; downstream sanitization issues being confused with this error.

Related errors


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