Skip to content
Betav0.62.0
All articles

Claude Code hooks can now fail closed when enforcement breaks

Claude Code v2.1.295 adds onFailure: block for command and HTTP hooks so missing scripts, timeouts and unexpected exits deny the action instead of failing open.

By The SpanDock team

4 min read

Diagram comparing default fail-open hook behaviour with onFailure block when a hook binary is missing

Policy hooks that fail open are a quiet compliance problem: the control looks present until the script path is wrong, the binary is missing, or the hook times out—and the tool call proceeds anyway. Claude Code v2.1.295 (8 October 2026) adds onFailure: "block" for command and HTTP hooks so those failures deny the action instead. Teams that use hooks as guardrails should treat the default as unsafe for high-assurance policies and opt into fail-closed behaviour deliberately.

Context: what onFailure block does

The release notes state that onFailure: "block" applies when a hook can't start, times out, or exits with an unexpected code: the action is blocked instead of being let through. The hooks reference documents onFailure on command and HTTP hooks as "continue" (default) or "block", requiring Claude Code v2.1.295 or later.

Exit-code behaviour was already nuanced. Exit 2 is the intentional blocking signal on events such as PreToolUse. Other non-zero exits were non-blocking errors unless you now set onFailure: "block". With "block", failures that previously only produced a hook-error notice can stop the tool call. The docs list what counts as failure: can't start, exit codes other than 0 or 2 (even with allow JSON on stdout), HTTP non-2xx or connection failure, timeout, and invalid JSON output.

That matters for managed settings and organisation policy hooks. A mistyped path in settings.json used to mean the hook never ran while the agent continued. Fail-closed turns that misconfiguration into a visible outage—which is the point for security controls.

Analysis: pair with the same week's permission fixes

The broader Claude Code changelog in the same period includes security-relevant permission work. Version 2.1.292 (6 October) fixed PreToolUse hook approvals and auto mode bypassing the permission prompt for file reads from network (UNC) paths, the one entry in that run marked as security. Version 2.1.295 itself also fixed Bash permission checks for for-loops over glob patterns. None of these fixes carries a CVE identifier.

Fail-closed hooks do not replace sandboxing (sandboxing coding agents) or prompt-injection defences (prompt injection to code execution). They close a specific gap: enforcement machinery that is present in config but absent at runtime. They also are not the same as SpanDock's product guardrails, though both can use Claude Code hooks as an enforcement channel.

Default continue remains appropriate for observational hooks (logging, metrics) where blocking would create unnecessary outages. Reserve "block" for hooks that encode allow/deny policy.

Rollout pattern that avoids surprise outages

Enable fail-closed first in a canary repository that already has a known-good hook pack. Confirm that intentional PreToolUse denials (exit code 2) still behave as before, then confirm that a deliberately broken path with onFailure: "block" stops the tool call. Only then roll the setting into managed organisation settings.

Document the difference between exit code 2 (policy denial) and other failures (infrastructure denial under fail-closed). On-call runbooks should say which alert means "the agent asked for something forbidden" versus "the hook binary is missing." Mixing those signals slows response.

If you distribute hooks as a private package, pin versions and verify signatures the same way you would for a security scanner. Fail-closed raises the cost of a broken package; it does not remove the need for supply-chain hygiene on the hook itself.

What it means for engineering and security leaders

Classify every hook as policy or telemetry. Only policy hooks should fail closed.

Expect noise after enabling block. Missing dependencies and wrong paths will stop developers. That is preferable to silent bypass, but needs a rollout plan and a known-good hook pack.

Managed hooks still need host health. Fail-closed cannot help if someone removes hooks entirely and your organisation does not reinstall them. Combine with configuration management.

Review UNC and Bash permission fixes when you upgrade. Fail-closed without patched permission bypasses leaves other holes open.

HTTP hooks need the same discipline

Command hooks fail when a binary is missing; HTTP hooks fail when the policy service is down, returns non-2xx, or times out. Under onFailure: "block", a regional outage of your policy API becomes a coding outage. That is acceptable for high-assurance environments if you run a highly available endpoint and a clear break-glass process. It is painful if the hook URL points at a single developer's laptop service. Prefer organisation-hosted policy endpoints with health checks before enabling fail-closed on HTTP hooks.

Practical takeaways for this week

  • Require Claude Code ≥2.1.295 before relying on onFailure: "block".
  • Set "onFailure": "block" on PreToolUse (and related) command/HTTP hooks that enforce security policy.
  • Leave logging-only hooks on the default continue.
  • Add a canary: temporarily rename a policy hook binary in a test project and confirm the tool call is denied.
  • Read the changelog entries on UNC path reads (2.1.292) and Bash glob permission checks (2.1.295) when you pick a target version.
  • Document who owns hook packages in each repository so broken paths are fixed quickly after fail-closed is on.

Where SpanDock fits

On Enterprise (and in the 30-day trial), SpanDock guardrails are rules set on the server and enforced on each computer. For Claude Code, Codex and Gemini CLI, SpanDock installs a hook that checks the prompt and every tool call before it runs. Matching stays on the computer; events record the rule and outcome, not the prompt text. Redaction of prompts and tool contents at the source is in every plan. See also guardrails keep secrets and personal data out of prompts. Pair product guardrails with fail-closed hook settings on any custom policy hooks you maintain yourself.

Sources

  1. Claude Code v2.1.295 release notes
  2. Claude Code hooks reference
  3. Claude Code changelog
Cookie categories

Details: Cookie Policy.