Tencent/WeKnora · error

image exceeds %d bytes limit

Error message

image exceeds %d bytes limit

What it means

downloadImage reads the remote image body through an io.LimitReader capped at maxRemoteImageSize+1 bytes; if the buffered body exceeds maxRemoteImageSize, the image is considered too large and downloadImage returns this error instead of storing it. It is a deliberate guard so oversized remote images do not exhaust memory or bloat converted documents.

Source

Thrown at internal/infrastructure/docparser/image_resolver.go:1044

	ct := resp.Header.Get("Content-Type")
	mimeType, _, _ = mime.ParseMediaType(ct)
	if mimeType == "" {
		mimeType = "application/octet-stream"
	}

	// Only allow image content types (or octet-stream which we sniff later).
	if !strings.HasPrefix(mimeType, "image/") && mimeType != "application/octet-stream" {
		return nil, "", fmt.Errorf("non-image content type: %s", mimeType)
	}

	// Read body with size limit.
	limited := io.LimitReader(resp.Body, maxRemoteImageSize+1)
	body, err := io.ReadAll(limited)
	if err != nil {
		return nil, "", fmt.Errorf("read body: %w", err)
	}
	if len(body) > maxRemoteImageSize {
		return nil, "", fmt.Errorf("image exceeds %d bytes limit", maxRemoteImageSize)
	}

	// If MIME was octet-stream, sniff the real type from body.
	if mimeType == "application/octet-stream" {
		detected := http.DetectContentType(body)
		if strings.HasPrefix(detected, "image/") {
			mimeType = detected
		} else {
			return nil, "", fmt.Errorf("downloaded data is not an image (sniffed: %s)", detected)
		}
	}

	return body, mimeType, nil
}

// extFromURLPath extracts the image file extension from the URL path segment.
func extFromURLPath(rawURL string) string {
	p := path.Ext(path.Base(rawURL))

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Resize or recompress the image at its source/CDN so it is under maxRemoteImageSize bytes.
  2. Raise the maxRemoteImageSize configuration value if your use case legitimately needs larger images.
  3. Replace the hotlinked image in the source document with a smaller one.
  4. Pre-download and inline the image locally so downloadImage is not invoked for it.

Example fix

// before: raw 12MB camera original linked in the doc
<img src="https://cdn.example.com/photos/IMG_0001.JPG" />
// after: serve a resized variant under the limit
<img src="https://cdn.example.com/photos/IMG_0001_w1600.jpg" />
Defensive patterns

Strategy: validation

Validate before calling

resp, err := http.Head(imgURL)
if err != nil { return err }
const maxRemoteImageSize = 10 << 20 // match library config
if resp.ContentLength > maxRemoteImageSize {
    return fmt.Errorf("image %s too large: %d > %d bytes", imgURL, resp.ContentLength, maxRemoteImageSize)
}

Try / catch

body, mdPath, err := resolver.fetchAndStoreRemoteImage(ctx, req, imgURL)
if err != nil {
    if strings.Contains(err.Error(), "bytes limit") {
        log.Warnf("skipping oversized remote image %s (limit exceeded)", imgURL)
        return nil // degrade gracefully: skip image, keep document text
    }
    return err
}

Prevention

When it happens

Trigger: fetchAndStoreRemoteImage -> downloadImage fetched a remote image whose response body length exceeds maxRemoteImageSize bytes (the LimitReader read back more bytes than the cap).

Common situations: Documents referencing huge product photos, unresized camera originals, or scans served from a CDN; someone raised the document size limit but not the remote image cap; hotlinked images that cannot be resized server-side.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/dc9113530624ae7c. Report an issue: GitHub.