ComfyUI Node

BrushNet Sampler

Masked Inpainting That Actually Respects the Mask

By kijai·Created 2 years ago·Updated 2 years ago· 150
BrushNet Sampler
  • brushnet
  • image
  • mask
  • images
steps25
cfg7.50
cfg_brushnet1.00
control_guidance_start0.00
control_guidance_end1.00
guess_modefalse
clip_skip0
seed0
schedulerUniPCMultistepScheduler
promptcaption
n_promptcaption

BrushNet Sampler is the workhorse of this pack: feed it an image, a mask, and a prompt, and it regenerates exactly the masked region with the surrounding pixels held in place. For its era this was the closest thing SD 1.5 had to "professional" inpainting, and the reason it beat the old inpaint-anywhere trick is architectural, not marketing.

How it works

BrushNet splits the job in two branches: one carries the masked image's features directly into the UNet's layers, the other carries the noisy latent being denoised. Because the model knows what's under the mask, it doesn't have to reconstruct the whole scene from a hole - it blends content into the region with coherent edges instead of smearing seams. The node pre-composites image * (1 - mask) before sampling, resizes your mask to match the image, and hands both to a diffusers pipeline.

Big practical consequence: this is a self-contained sampler. There's no KSampler in the graph - the node builds and runs the whole pipeline internally, with its own scheduler dropdown (default UniPCMultistepScheduler) and its own seed. It also flips on model CPU offload once per session, so it'll squeeze onto smaller cards, at the cost of being slower than a native ComfyUI sampler.

The inputs that matter

Most are standard, so here's the short list a beginner actually touches:

  • image and mask - your source image and the region to regenerate. Mask should be white where you want new content.
  • prompt / n_prompt - describe what should appear in the masked area.
  • cfg_brushnet - the strength of the BrushNet condition itself (default 1.0). This is the dial to grab when content ignores your mask (raise it) or when edges get stiff (lower it).
  • control_guidance_start / control_guidance_end - like ControlNet's start/end: which slice of denoising the condition applies to. Release it early (e.g. end 0.6) to let the model add detail in late steps.
  • guess_mode (off by default), clip_skip, steps, cfg, seed, scheduler - the usual suspects.

Output is images (an IMAGE tensor). Note that you generally re-composite it over the original with a mask-composite node - the example workflows ship with ImageCompositeMasked wired for exactly that.

Two hard constraints

First, SD 1.5 only - the loader builds from the v1-inference config, so an SDXL checkpoint here is a no-go. Second, the node asserts the loaded model isn't PowerPaint: if you load powerpaint_v2_brushnet, the plain sampler refuses and you must use the PowerPaint BrushNet Sampler instead. It also can't run at all without a BrushNet Model Loader output feeding its brushnet input.

Installing and troubleshooting

Same pack as everything here: Manager search "BrushNet", or git clone https://github.com/kijai/ComfyUI-BrushNet-Wrapper into custom_nodes, then pip install -r requirements.txt (portable users: python_embeded\python.exe -m pip install -r ComfyUI\custom_nodes\ComfyUI-BrushNet-Wrapper\requirements.txt), restart. Weights auto-download to ComfyUI/models/brushnet.

Common pain points, from the code and the community: a mask that's larger than the image causes a resize/error - keep it same-size; the first run downloads fp16 weights and looks frozen; and if outputs look "washed out," the usual culprit is a mismatch between the composite node's mask and the mask you sampled with. And a fair warning for 2026: mask-based inpainting has mostly been displaced by instruction-editing models (Qwen-Image-Edit, Flux Kontext), which don't need a mask at all. What BrushNet still uniquely gives you is bit-identical unmasked pixels - the region outside the mask doesn't drift. If you need that, it's worth the setup. If you don't, the edit models are less fuss.

CategoryBrushNetWrapper

Inputs (14)

NameTypeDefaultDescription
brushnetBRUSHNET
imageIMAGE
maskMASK
stepsINT251–200
cfgFLOAT7.500–20
cfg_brushnetFLOAT1.000–20
control_guidance_startFLOAT0.000–1
control_guidance_endFLOAT1.000–1
guess_modeBOOLEANfalse
clip_skipINT00–20
seedINT00–18446744073709550000
schedulerCOMBOUniPCMultistepScheduler10 options: DPMSolverMultistepScheduler, DPMSolverMultistepScheduler_SDE_karras, DDPMScheduler, LCMScheduler, PNDMScheduler, DEISMultistepScheduler, +4
promptSTRINGcaption
n_promptSTRINGcaption

Outputs (1)

NameTypeDescription
imagesIMAGE