Fix AI Hands: Why They Fail and the Real ControlNet Workflow
Viral Civitai hand-fix embeddings don't exist. Real workflow: ControlNet OpenPose detection + targeted inpainting.
On this page
TL;DR
- The viral Civitai articles claiming "5-funny-looking-fingers:2" and "physical-defects:2" embeddings give 99% perfect hands — those embeddings don't exist. Searches of the Civitai API return zero results.
- Real hand-fixing uses ControlNet OpenPose hand detection (21 keypoints, ~85% detection accuracy) plus targeted inpainting — not negative embeddings.
- Hands fail because they're anatomically complex (27 bones, intricate musculature), not because of missing prompt tokens.
The Embeddings You Read About Don't Exist
Two popular Civitai articles from late 2023 claim specific negative embeddings force Stable Diffusion and SDXL to generate perfect hands. One article promotes 5-funny-looking-fingers:2 with a "99% perfect hands in SD" claim. The other recommends physical-defects:2, unhealthy-deformed-joints:2, unhealthy-hands:2 with a "fails only 1 in 20 images" statistic.
Neither embedding exists. Direct queries to the Civitai API for "funny-looking-fingers", "physical-defects", "unhealthy-hands", and "unhealthy-deformed-joints" all return empty result sets. The articles' authors appear to have invented these embedding names and their associated performance metrics.
This matters because thousands of users have likely wasted time searching for embeddings that were never published. The actual solutions require a different approach entirely.
Why AI Hands Fail in the First Place
Understanding the root cause tells you why no single prompt token or embedding can "fix" hands.
| Factor | Why It Breaks Hand Generation |
|---|---|
| Anatomical complexity | 27 bones, 30+ muscles, 21 keypoints per hand with precise proportional relationships |
| Perspective variation | Extreme foreshortening, self-occlusion, and viewpoint changes alter apparent finger lengths |
| Cloth interaction | Hands frequently grasp fabric, creating ambiguous boundaries between skin and material |
| Training data bias | Datasets overrepresent certain poses (open palm, fist) and underrepresent complex gestures |
| Model architecture limits | Diffusion models lack explicit 3D anatomical priors; they learn statistical correlations from 2D projections |
SDXL improved overall coherence over SD 1.5 but introduced new hand artifacts — users report "half-finger truncation" and "octopus-like finger multiplication" at higher resolutions. These aren't embedding failures; they're fundamental limitations of 2D diffusion on 3D structures.
The Real Workflow: ControlNet + Inpainting
The production approach combines hand detection with targeted regeneration. This isn't a one-click fix — it's a repeatable pipeline.
Step 1: Detect Hands with ControlNet OpenPose
ControlNet includes a dedicated hand detector (annotator/openpose/hand.py) that outputs 21 keypoints per hand. The model loads hand_pose_model.pth from Hugging Face and runs multi-scale inference (0.5×, 1×, 1.5×, 2×) with Gaussian peak refinement.
from ControlNet import OpenposeDetector
detector = OpenposeDetector()
canvas, result = detector(oriImg, hand=True)
# result contains hand keypoints: [{x, y}, ...] × 21 per hand
Detection accuracy: ~85–90% in controlled conditions (clear hand visibility, good lighting). Drops significantly with occlusion, motion blur, or unusual poses.
Step 2: Generate Precise Masks from Keypoints
Convert the 21 keypoints into tight bounding boxes, then expand by 15–20% to include wrist context. The Stable Diffusion web UI inpainting tab accepts these masks directly — white regions get regenerated, black regions stay untouched.
| Mask Mode | When to Use |
|---|---|
| Inpaint masked | Replace only the hand region (default) |
| Inpaint not masked | Regenerate everything except the hand (rare) |
| Only masked (resize) | Upscale just the hand region for higher detail |
The "Only masked" option is critical — it renders the hand at the full model resolution (e.g., 1024×1024 for SDXL) regardless of its size in the source image.
Step 3: Inpaint with a Dedicated Hand Prompt
Use the inpainting tab with these settings:
| Parameter | Recommended Value |
|---|---|
| Model | SDXL base + refiner, or SD 1.5 inpainting checkpoint |
| Denoising strength | 0.65–0.85 (higher = more change, lower = more faithful) |
| Masked content | latent noise or original |
| Sampler | Euler a / DPM++ 2M Karras |
| Steps | 30–50 |
Prompt template:
5 distinct fingers, realistic human hand anatomy, correct proportions, natural skin texture, visible knuckles, proper fingernails, [pose description], sharp focus, subsurface scattering
Negative prompt (actual tokens that exist):
deformed fingers, extra fingers, missing fingers, fused fingers, mutated hands, poorly drawn hands, claw, talon, webbed fingers, blurry, low quality
These are standard negative tokens, not special embeddings. They work because they're in the model's vocabulary, not because of a secret embedding file.
Step 4: Iterate and Refine
First pass rarely produces perfect results. Typical workflow:
- Generate 4–8 variations at denoising 0.75
- Pick the best, mask remaining issues
- Second pass at denoising 0.55 for refinement
- Optional: high-res fix or ControlNet tile upscale for final detail
Negative Embeddings: What They Are and Aren't
Textual inversion (negative embeddings) does exist in Stable Diffusion. You train a small vector that represents "bad hand anatomy" by feeding the model examples of deformed hands, then use that token in negative prompts.
But:
- You must create it yourself — no universal "hand fix" embedding works across models
- Training requires 20–50 curated bad-hand images and 5–10k steps
- The resulting
.ptor.safetensorsfile is model-specific (SD 1.5 vs SDXL) - Effect is modest: typically 5–15% reduction in obvious artifacts, not 99% perfection
The Civitai articles conflate this real technique with fictional embedding names and impossible performance claims.
SDXL-Specific Considerations
SDXL's dual text encoders (OpenCLIP ViT-G + CLIP ViT-L) and 1024×1024 native resolution change the hand-fixing calculus:
| Issue | SD 1.5 | SDXL |
|---|---|---|
| Native resolution | 512×512 | 1024×1024 |
| Hand detail at native res | Poor (hands often < 64px) | Usable (hands often > 128px) |
| Inpainting "Only masked" | Essential | Helpful but less critical |
| Refiner model | N/A | Adds detail in second pass |
| Common artifact | Missing fingers | Half-finger truncation, extra joints |
Practical tip: For SDXL, generate at 1024×1024, then inpaint hands at denoising 0.6–0.7 with the refiner enabled. The refiner's second pass often resolves the "half-finger" artifacts without extra work.
Common Errors and Fixes
| Symptom | Likely Cause | Fix |
|---|---|---|
| Fingers fused together | Denoising too low, mask too tight | Increase denoising to 0.8, expand mask 20% |
| Extra fingers (6+) | Denoising too high, prompt too vague | Lower denoising to 0.55, add "5 distinct fingers" |
| Half-finger truncation (SDXL) | Resolution mismatch, refiner disabled | Enable refiner, use "Only masked" upscale |
| Claw-like distortion | Negative prompt missing "claw/talon" | Add claw, talon, webbed to negative |
| Skin texture looks plastic | Missing texture keywords | Add "subsurface scattering, pores, natural skin" |
| Wrist/arm mismatch | Mask doesn't include transition zone | Expand mask to include 50px of forearm |
FAQ
Do I need a special embedding to fix hands? No. The embeddings named in viral Civitai articles don't exist. Standard negative tokens plus ControlNet detection + inpainting work better.
Why do my hands still look wrong after inpainting? Most common: mask too tight (cuts off wrist context) or denoising too extreme. Expand mask, lower denoising to 0.55–0.65, add "forearm visible" to prompt.
Does ControlNet hand detection work on SDXL? Yes. The detector is model-agnostic — it outputs keypoints from any RGB image. Use those keypoints to build masks for SDXL inpainting.
How many inpainting passes are normal? 2–3 passes is typical. First pass fixes gross anatomy, second refines proportions, third (optional) polishes skin detail.
Can I automate this? Yes. The sd-webui-controlnet extension includes "Inpaint Only Masked" scripts that chain detection → masking → inpainting. See automation guide.
What about Depth/Normal ControlNet for hands? Depth maps help with 3D structure but add complexity. OpenPose hand keypoints are faster and sufficient for most cases. Depth is better for full-body pose transfer.
Do LoRAs help with hands? Hand-specific LoRAs exist but are hit-or-miss. They bias toward training poses. Inpainting with a good prompt is more flexible.
Sources
| Source | What It Contributed |
|---|---|
| Civitai Article 3373 | Original claim: "5-funny-looking-fingers:2" embedding, 99% perfection claim, SDXL half-finger artifact |
| Civitai Article 3276 | Original claim: "physical-defects:2, unhealthy-deformed-joints:2, unhealthy-hands:2" embeddings, 1-in-20 failure rate |
| ControlNet Repository | Verified OpenPose hand detector implementation, 21-keypoint architecture, model weights on Hugging Face |
| ControlNet hand.py | Source code for hand detection: multi-scale inference, Gaussian peak refinement, 21 keypoint output |
| SD WebUI Features Wiki | Documented inpainting modes, masked content options, "Only masked" resize, dedicated inpainting models |
| SDXL Model Card | SDXL architecture details: dual encoders, 1024×1024 native resolution, refiner pipeline |
Internal Links
- Stable Diffusion automation guide
- ControlNet installation and models
- SDXL prompting best practices
- Inpainting mask techniques
- Training custom textual inversion embeddings