Every frame carries what got subtracted, not just what got kept.
Negative prompting isn't a filter you type into. It's half of a two-pass calculation, and Flux dev only runs one pass.
Somebody switches a workflow from SDXL to Flux, keeps their usual negative prompt pasted into the second CLIP Text Encode node out of habit, "blurry, bad hands, watermark, extra fingers, low quality," and the renders don't visibly change whether that box is full or empty. They assume the workflow is broken. It isn't. The box just stopped being connected to anything that matters.
That mix-up is common enough to be worth unpacking properly, because negative prompting was never a content filter. It's the visible half of a specific arithmetic trick, and once you know what the trick is, it's obvious why one major model family opted out of it.
Text-to-image diffusion models don't generate an image directly from a text prompt. At each denoising step, the model predicts noise twice: once conditioned on your prompt, and once conditioned on nothing, or on whatever sits in the negative box. Classifier-free guidance takes the difference between those two predictions and pushes the image further in that direction. Roughly: final_prediction = uncond_prediction + cfg_scale × (cond_prediction - uncond_prediction).
Leave the negative box empty and uncond_prediction is the model's guess at "an image, no description at all." Type "blurry, extra fingers, watermark" into it and uncond_prediction becomes the model's guess at an image matching that description instead. The formula doesn't change. What changes is which direction counts as away.
That's the whole mechanism. A negative prompt isn't excluding pixels, it's relocating the reference point that the positive prompt gets extrapolated away from. It works because SD1.5 and SDXL run both passes, cond and uncond, every single step, and CFG scale controls how hard the result gets pushed along the line between them.
Flux.1, from Black Forest Labs, is a different architecture running a different training recipe, and the dev checkpoint specifically is what's called guidance-distilled. During training, the model was taught to reproduce the output of running full two-pass classifier-free guidance, but to do it in a single forward pass instead of two. The guidance strength gets baked into the model's behavior at training time rather than computed live at inference time from a real negative pass.
Practically, that means the standard Flux dev workflow sets cfg to 1.0 in the KSampler, which disables the traditional two-pass CFG loop entirely, and controls prompt strength instead through a separate FluxGuidance node whose documented default value is 3.5. Push that value toward 4 or 5 for tighter adherence on short prompts, pull it toward 2 or 3 for more interpretive results on longer ones. There's no live uncond pass in that path for a negative prompt to redirect, so whatever you type into the negative box in a stock Flux dev workflow is talking to a room nobody's in.
| Model | Guidance mechanism | Negative prompt effect |
|---|---|---|
| SD1.5 / SDXL | Live two-pass CFG, cond and uncond every step | Directly reshapes the uncond reference point |
| Flux.1 dev (standard workflow) | Distilled single pass, cfg locked near 1.0 | Effectively unused, no live uncond pass to feed |
| Flux.1 dev ("true CFG" workflow) | Restored two-pass CFG, custom nodes | Works again, at roughly double the compute per step |
That last row matters if you actually need exclusion, not just adherence. The community response has been to build workflows that reintroduce a real second pass on top of Flux anyway. Community "true CFG" and "efficient negative prompt" node setups run a genuine conditioned and unconditioned pass and recombine them, functionally undoing part of the distillation to get a working negative prompt back. It costs close to double the per-step compute, since you're back to two model calls instead of one, and that tradeoff is exactly why Black Forest Labs distilled it away for the default path in the first place: most users want speed and strong prompt-following more than they want a working exclusion mechanism.
Since the negative box is mostly inert in the default workflow, the practical fix is moving that intent into the positive prompt as explicit direction rather than exclusion. Flux's prompt-following is strong enough that describing what you want tends to outperform describing what you don't. "Sharp focus, clean hands, five fingers per hand" in the positive prompt does more work on Flux dev than "blurry, bad hands" in a negative box that isn't wired to anything.
For genuine content exclusion on Flux, specifically keeping a concept out rather than just steering away from it, the honest answer is either the true-CFG workflow at double the render time, or catching the problem after generation with a targeted inpaint pass instead of trying to prevent it at the conditioning stage.
The common take is that Flux "doesn't support negative prompts," full stop, end of discussion. That's not quite right and it undersells what's actually happening. Flux supports negative prompting the same way any diffusion model can, through a second conditioned pass, it's just that the default distilled checkpoint was specifically trained to skip that pass for speed. The capability was traded away on purpose, not missing by accident, and it can be bought back with the true-CFG approach whenever the tradeoff is worth it.
The counterpoint people raise, reasonably, is that if a workaround exists, why doesn't Black Forest Labs just ship it enabled. The answer is that most Flux renders are judged on prompt adherence and speed, not on excluding specific unwanted elements, and doubling compute for every single generation to fix a problem most prompts don't have is a bad default. It's a good option, not a good default.
If you've been copying the same negative prompt block across every workflow regardless of base model, open your Flux dev graph and check what cfg is actually set to in the KSampler. If it reads 1.0, that negative conditioning has nowhere to go. Delete it, move the intent into the positive prompt as explicit description, and see whether the render actually changes when you toggle it. On SDXL it will. On stock Flux dev, it mostly won't, and now you know exactly why.