invoke-ai/InvokeAI · error · RuntimeError

image too small, should be larger than 256x256

Error message

image too small, should be larger than 256x256

What it means

The vendored invisible-watermark encoder requires images with at least 256*256 pixels (r*c >= 65536) because the DCT-based embedding needs enough frequency blocks; smaller images raise RuntimeError.

Source

Thrown at invokeai/backend/image_util/imwatermark/vendor.py:84

            self.set_by_bits(content)
        elif wmType == "bytes":
            self.set_by_bytes(content)
        elif wmType == "b16":
            self.set_by_b16(content)
        else:
            raise NameError("%s is not supported" % wmType)

    def get_length(self):
        return self._wmLen

    # @classmethod
    # def loadModel(cls):
    #     RivaWatermark.loadModel()

    def encode(self, cv2Image, method="dwtDct", **configs):
        (r, c, channels) = cv2Image.shape
        if r * c < 256 * 256:
            raise RuntimeError("image too small, should be larger than 256x256")

        if method == "dwtDct":
            embed = EmbedMaxDct(self._watermarks, wmLen=self._wmLen, **configs)
            return embed.encode(cv2Image)
        # elif method == 'dwtDctSvd':
        #     embed = EmbedDwtDctSvd(self._watermarks, wmLen=self._wmLen, **configs)
        #     return embed.encode(cv2Image)
        # elif method == 'rivaGan':
        #     embed = RivaWatermark(self._watermarks, self._wmLen)
        #     return embed.encode(cv2Image)
        else:
            raise NameError("%s is not supported" % method)


class WatermarkDecoder(object):
    def __init__(self, wm_type="bytes", length=0):
        self._wmType = wm_type
        if wm_type == "ipv4":

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Upscale the image to at least 256x256 (total >= 65536 pixels) before encoding
  2. Watermark the full-resolution image first, then downscale afterward
  3. Skip watermarking for images below the size threshold with a graceful fallback

Example fix

// before
encoder.encode(small_img, "dwtDct")  # 180x200
// after
if small_img.shape[0] * small_img.shape[1] < 256 * 256:
    small_img = cv2.resize(small_img, (256, 256))
encoder.encode(small_img, "dwtDct")
Defensive patterns

Strategy: validation

Validate before calling

h, w = image.shape[:2]
if h * w < 256 * 256:
    image = cv2.resize(image, (max(256, w), max(256, h)), interpolation=cv2.INTER_CUBIC)

Type guard

def is_watermarkable(image) -> bool:
    r, c = image.shape[0], image.shape[1]
    return r * c >= 256 * 256

Try / catch

try:
    encoded = encoder.encode(image, "dwtDct")
except RuntimeError as e:
    if "image too small" in str(e):
        image = cv2.resize(image, (max(256, image.shape[1]), max(256, image.shape[0])))
        encoded = encoder.encode(image, "dwtDct")
    else:
        raise

Prevention

When it happens

Trigger: Calling encode() (via add_watermark) on images smaller than 256x256 in total pixel count — e.g. 128x512 thumbnails, 200x300 crops, or small icon outputs.

Common situations: Generating small preview images, watermarking downscaled thumbnails, resizing outputs below the threshold before watermarking.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/28d876ba0cebb5ef. Report an issue: GitHub.