Mask Fill Hole
Fill the donut holes in your masks — auto-cutout masks are full of them
- mask
- mask
Automatic masking is leaky in a specific, predictable way: a subject mask comes back with tiny holes where the model decided a bit of background or shadow "probably isn't the subject." A donut-shaped mask - a person with a hole where their arm crosses the background, a product with a gap inside its silhouette. If you feed that straight into an inpaint or a cutout, you get artifacts in exactly those spots.
Mask Fill Hole is the two-second fix: it fills every enclosed hole inside a mask's solid regions, turning the donut into a solid disc. It's been in the pack since v1.2.5, and it's one of those tiny nodes you end up reaching for constantly once you know it exists.
How it works
Mechanically it's scipy's binary_fill_holes: the mask is thresholded to binary, any fully-enclosed black region surrounded by white is flipped to white, and everything else is left alone. The key distinction is enclosed - a hole that touches the mask's outer boundary isn't filled, because that's not a hole, that's the shape of the mask. So a C-shaped mask stays a C; only the closed loops inside get filled.
Two inputs:
mask- the batch to clean. It's fully batch-safe and threaded across CPU cores, so a 100-frame mask batch processes in a blink.invert_mask- off by default. Flip it and the logic inverts: it fills holes in the background instead (i.e., fills the enclosed white islands inside the black region). Useful when you're working with an inverted-mask convention.
Output is mask, same size and batch count as the input.
Where you'd use it
Anywhere an auto-detector gave you a holey mask and you want a clean, single region: after background removal, after SAM, after a segmentation pass, before feeding a mask into an inpaint or a stroke node. It pairs nicely with the pack's Image Stroke by Mask - outline the filled mask so the stroke doesn't wander through interior holes. And because it's batch-native, you can run it across every frame of a video mask set in one go.
Installing it
Part of 1hewNodes. ComfyUI Manager → search "ComfyUI 1hewNodes" → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/1hew/ComfyUI-1hewNodes
Restart ComfyUI. It needs scipy for the fill operation - that's in the pack's requirements, so Manager installs it automatically.
Common issues
The boundary rule trips people up: this fills enclosed holes only. A hole open to the mask's edge won't be filled, and no amount of re-running will change that - if you want a truly convex fill, you need a different operation (the pack's "Mask to BBox Mask" gives you the bounding-box version). Also, remember invert_mask flips which side gets filled, not whether filling happens - if you enable it and the output looks inverted relative to your expectations, that's what's happening. And semi-transparent (soft-edged) masks get thresholded on the way through, so a feathered mask will harden - run it before you add any blur, not after.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| invert_mask | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |