AUTOMATIC1111/stable-diffusion-webui · error · ValueError

File cannot be fetched: {item}. Failed to load cover image.

Error message

File cannot be fetched: {item}. Failed to load cover image.

What it means

Final stage of fetch_cover_images(): the selected base64 entry must be decodable by b64decode and openable by PIL, then re-saved. Any exception in that chain (binascii.Error from bad base64, PIL.UnidentifiedImageError from non-image bytes) is re-raised as this ValueError naming the item.

Source

Thrown at modules/ui_extra_networks.py:136

    if page is None:
        raise HTTPException(status_code=404, detail="File not found")

    metadata = page.metadata.get(item)
    if metadata is None:
        raise HTTPException(status_code=404, detail="File not found")

    cover_images = json.loads(metadata.get('ssmd_cover_images', {}))
    image = cover_images[index] if index < len(cover_images) else None
    if not image:
        raise HTTPException(status_code=404, detail="File not found")

    try:
        image = Image.open(BytesIO(b64decode(image)))
        buffer = BytesIO()
        image.save(buffer, format=image.format)
        return Response(content=buffer.getvalue(), media_type=image.get_format_mimetype())
    except Exception as err:
        raise ValueError(f"File cannot be fetched: {item}. Failed to load cover image.") from err


def get_metadata(page: str = "", item: str = ""):
    from starlette.responses import JSONResponse

    page = next(iter([x for x in extra_pages if x.name == page]), None)
    if page is None:
        return JSONResponse({})

    metadata = page.metadata.get(item)
    if metadata is None:
        return JSONResponse({})

    metadata = {i:metadata[i] for i in metadata if i != 'ssmd_cover_images'}  # those are cover images, and they are too big to display in UI as text

    return JSONResponse({"metadata": json.dumps(metadata, indent=4, ensure_ascii=False)})


View on GitHub (pinned to 82a973c043)

Solutions

  1. Strip any 'data:image/...;base64,' prefix and all whitespace/newlines from the stored value
  2. Validate offline: PIL.Image.open(BytesIO(base64.b64decode(s, validate=True))) on each entry, and fix/remove the bad one
  3. Re-generate the cover metadata with the extension/tool that owns it rather than editing JSON by hand

Example fix

# before
"ssmd_cover_images": ["data:image/png;base64,iVBOR..."]
# after
"ssmd_cover_images": ["iVBOR..."]
Defensive patterns

Strategy: try-catch

Validate before calling

import base64, io
from PIL import Image
def cover_entry_ok(b64: str) -> bool:
    try:
        raw = b64.split(',')[-1].strip().replace('\n', '').replace(' ', '')
        Image.open(io.BytesIO(base64.b64decode(raw, validate=True)))
        return True
    except Exception:
        return False

Try / catch

try:
    resp = fetch_cover_images(...)  # or direct PIL decode
except ValueError as e:
    if 'Failed to load cover image' in str(e):
        drop_bad_cover_metadata(item)

Prevention

When it happens

Trigger: ssmd_cover_images containing base64 that is truncated, contains data-URI prefixes ('data:image/png;base64,...'), whitespace/newlines some decoders reject in strict mode, or bytes that are not an image at all.

Common situations: Hand-pasted or script-generated metadata with data-URI prefixes; Civitai exporter tools writing slightly different base64; JSON escaped with wrapping newlines every 76 chars (MIME style).

Related errors


AI-assisted analysis of AUTOMATIC1111/stable-diffusion-webui@82a973c043 (2026-08-14). Data as JSON: /api/errors/9298c43cf8d61ccb. Report an issue: GitHub.