Nodes/ComfyUI/Grow Mask
ComfyUI Node Runs on cloud

Grow Mask

The padding your inpaints never knew they needed

By Comfy-Org·Created 4 years ago·Updated about 3 hours ago· 129,870
Grow Mask
  • mask
  • MASK
expand0
tapered_cornerstrue

Grow Mask is the node you didn't know you were missing until your first inpainted fix came out looking like someone cut a hole and glued the patch in. It expands or shrinks a mask by a set number of pixels, and that one move fixes more mask problems than any other trick in ComfyUI. If you've ever wondered why your inpainting looks like a sticker, the answer is usually that you never gave the model any room to blend.

Why you'll reach for it

A mask in ComfyUI is a [B,H,W] float tensor where 1.0 means "regenerate here" and 0.0 means "leave this alone." The problem is that the region you paint is rarely the region the model needs. Inpainting wants context: the model blends best when there's a ring of original pixels around the fix, which is why every serious inpainting recipe grows the mask a little before it hits the sampler. A1111 calls this "inpaint at full resolution padding"; ComfyUI's VAE Encode (for inpainting) even has a grow_mask_by input, capped at 64 pixels. Grow Mask is the standalone version with no cap, so it works anywhere.

The other classic use is shrinking, and it's the fix for a specific, infuriating artifact: the white halo ring around a composited subject. IC-Light users learn this one fast - the standard advice is to "choke the mask by 1px and premultiply the alpha" before compositing. A negative expand does the choking.

How it works

For each pixel of expand, the node applies a 3x3 morphological operation - scipy's grey dilation if you're growing, grey erosion if you're shrinking. Repeated abs(expand) times. That last part matters more than you'd think, because it runs in plain Python on the CPU, one mask at a time. Grow by 200 pixels and you're doing 200 sequential passes over a numpy array. It's fine for a 512x512 mask, but keep an eye on it for big values on large masks - it's the slowest step in an otherwise-GPU pipeline, and there's nothing clever about it.

tapered_corners (on by default) changes the kernel from a full 3x3 square to a cross. A cross grows edges but leaves the diagonals to catch up, which keeps corners from turning into blocky steps. Turn it off if you want the corners to extend at the same rate as the edges - for most people the default is right, and the "tapered" look is usually what you actually wanted.

The inputs that matter

  • mask - what you're growing or shrinking.
  • expand - pixels to add (positive) or remove (negative). This is the whole job. Zero is a no-op.
  • tapered_corners - leave it on.

One output, MASK, which you feed straight into VAE Encode (for inpainting), a ControlNet inpaint condition, or a composite node.

Getting it

It ships with ComfyUI core, no install. It lives in comfy_extras/nodes_mask.py alongside the rest of the built-in mask family, and it's been there since the early days - this is one of the oldest nodes in the graph.

Where people get burned

  • Expecting GPU speed. It's scipy on the CPU; big expand values on big masks stall the queue. If you need huge padding, feather instead, or accept the wait.
  • Shrinking leaves hard edges. Erode a mask and you get a crisp cliff, which reintroduces the seam you were trying to kill. Chain it into FeatherMask afterwards - grow for context, then feather to blend.
  • Forgetting the mask is your contract. Grow the mask, and the model now owns that extra ring of pixels too. More padding = more context but also more of the image subject to change. The 2026 consensus is 4–12px of blur and modest padding, not "grow it a mile."
Categoryimage/mask

Inputs (3)

NameTypeDefaultDescription
maskMASK
expandINT0-16384–16384
tapered_cornersBOOLEANtrue

Outputs (1)

NameTypeDescription
MASKMASK