Claude Code Hooks Can Now Fail Closed With onFailure
Claude Code 2.1.295 adds an onFailure: "block" option for command and HTTP hooks. When set, a hook that cannot start, times out, or exits with an unexpected code blocks the action instead of letting it through. This closes a long-standing gap where a broken guard hook silently stopped guarding anything.
Key Takeaways
- Hooks can now fail closed, so a hook that cannot start, times out, or exits unexpectedly blocks the action instead of letting it through.
- The new setting is
onFailure: "block", available on command and HTTP hooks. - Previously, a broken or unreachable guard hook silently stopped enforcing the rule it was written for.
- The behavior is opt-in per hook, so existing hooks keep their current fail-open behavior.
- Policy hooks that depend on network services or locally installed tools gain the most, since outages no longer disable them.
- Advisory hooks such as logging or notifications can stay fail-open while enforcement hooks are tightened.
A guard hook that fails no longer waves things through
Hooks are the main way Claude Code users enforce their own rules: a PreToolUse hook that inspects a shell command, an HTTP hook that asks an internal policy service, a script that rejects edits to protected files. Until now, those hooks had a quiet weakness. If the hook could not start, took too long, or exited with a code Claude Code did not expect, the action simply went ahead. A missing interpreter or an unreachable policy server could turn a strict guardrail into no guardrail at all.
Claude Code 2.1.295 adds an onFailure: "block" setting for command and HTTP hooks. With it enabled, any of those three failure modes (failing to start, timing out, or an unexpected exit code) now blocks the action rather than allowing it. The hook fails closed.
Why it matters
For anyone using hooks as a safety net, the difference is substantial. A policy check that depends on a network call to an internal service is only as reliable as that service. With fail-closed behavior, an outage means Claude Code pauses the action instead of proceeding unchecked. The same applies to hooks that rely on a local tool that may not be installed on every machine, such as a linter or secret scanner.
The setting is opt-in per hook, so existing configurations keep their current behavior. Teams that treat a hook as a hard requirement can add onFailure: "block" to those specific hooks, while leaving advisory hooks, such as notifications or logging, as they are.
What to do
Review the hooks that enforce rules rather than merely report. Any hook where a silent failure would be worse than a blocked action is a candidate for onFailure: "block". Pair it with a reliable timeout so that a slow policy service produces a clear block rather than a long stall.