Claude Code hooks can now fail closed with onFailure

Claude Code 2.1.295 (October 8, 2026) adds an onFailure field to command and http hooks. It lets a policy hook fail closed.

The old default fails open

Until now, a hook that broke did not stop anything. A hook that exits with any code other than 0 or 2, fails to start, or prints invalid JSON is a non-blocking error. The action goes ahead, and you see a <hook name> hook error notice in the transcript.

A timeout behaves the same way on PreToolUse. A timed-out command, http, or mcp_tool hook does not block the tool call. The call continues through the normal permission flow.

So a policy hook with a wrong script path, or one that crashes, lets everything through.

The field

onFailure takes "continue" (the default) or "block". This PreToolUse hook in .claude/settings.json blocks a Bash command if its script fails:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "node",
            "args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.js"],
            "onFailure": "block"
          }
        ]
      }
    ]
  }
}

To test it, leave check-command.js missing and ask Claude to run ls. The call is blocked, and the error includes failed; blocking because onFailure is "block". After a timeout, the message says timed out instead of failed. Without the field, the same missing script is a non-blocking error and ls runs.

What counts as a failure

Prompts too

The same field applies to UserPromptSubmit. A command, HTTP, or MCP tool hook there that reaches its timeout is canceled, and its output, including any additionalContext, is discarded. The prompt still reaches Claude without that context. Set onFailure: "block" on a command or HTTP hook to block the prompt instead.

What to do

If a hook is a gate rather than a convenience, add "onFailure": "block". Then run it once with the script missing and confirm the action is refused. Leave advisory hooks, such as formatters and loggers, on the default.