How to fix commit-msg hook failure in Git

GitBEGINNERLOWUpdated Dec 6, 2025ยท 231 views

This error occurs when Git's commit-msg hook rejects your commit message. The hook validates message format (like conventional commits) and exits non-zero when validation fails. Fix by formatting your message correctly or bypassing the hook.

Quick fix

Fixes commit-msg hook failure

husky - commit-msg hook exited with code 1 (error)
subject may not be empty [subject-empty]
type must be one of [feat, fix, docs, style, refactor, test, chore] [type-enum]
  1. Read the error message carefully
  2. Use the correct commit message format
  3. Recover your rejected commit message
  4. Check hook script for errors
git โ€” error
husky - commit-msg hook exited with code 1 (error)
subject may not be empty [subject-empty]
type must be one of [feat, fix, docs, style, refactor, test, chore] [type-enum]
commit-msg hook failure

What this error means

The commit-msg hook is a Git hook that runs after you write your commit message but before the commit is finalized. It receives the path to a temporary file containing your commit message as its only argument. If the hook script exits with a non-zero status code, Git aborts the commit entirely. This hook is commonly used to enforce commit message conventions in a project. Popular tools like commitlint, gitlint, and custom validation scripts use this hook to ensure all commits follow a consistent format such as Conventional Commits (e.g., `feat: add new feature`, `fix: resolve bug`). When the hook fails, it means your commit message didn't pass the validation rules defined in the hook script. The commit is rejected, but your message is preserved in `.git/COMMIT_EDITMSG` so you can fix and retry without retyping everything.

Typical symptoms

  • Git commit command fails with 'commit-msg hook failure' or similar message
  • Husky or pre-commit framework displays validation errors about commit message format
  • Error mentions commitlint, gitlint, or similar tool rejecting the message
  • Commit works when using --no-verify flag but fails normally
  • CI/CD pipeline fails at commit validation step

Common causes

  1. Commit message doesn't follow required format (e.g., Conventional Commits)
  2. Message is missing a required type prefix like feat:, fix:, or chore:
  3. Subject line exceeds maximum length limit (commonly 50-72 characters)
  4. Missing blank line between subject and body
  5. Hook script itself has errors (syntax issues, wrong shebang, not executable)
  6. Hook file has Windows line endings (CRLF) instead of Unix (LF)

How to fix "commit-msg hook failure"

1Read the error message carefully

The commit-msg hook typically outputs exactly what's wrong with your message. Look for output like:

bash
husky - commit-msg hook exited with code 1 (error)
subject may not be empty [subject-empty]
type must be one of [feat, fix, docs, style, refactor, test, chore] [type-enum]

This tells you exactly which rules your message violated.

2Use the correct commit message format

If your project uses Conventional Commits, format your message as:

bash
<type>(<optional scope>): <description>

[optional body]

[optional footer]

Valid types include:
- feat: - New feature
- fix: - Bug fix
- docs: - Documentation changes
- style: - Formatting, no code change
- refactor: - Code restructuring
- test: - Adding/updating tests
- chore: - Maintenance tasks

Examples of valid messages:

bash
git commit -m "feat: add user authentication"
git commit -m "fix(api): resolve null pointer in login handler"
git commit -m "docs: update README with installation steps"
3Recover your rejected commit message

When a commit fails, your message is saved to .git/COMMIT_EDITMSG. You can recover and edit it:

bash
# View your rejected message
cat .git/COMMIT_EDITMSG

# Create a new commit with the saved message, opened in editor
git commit -e -F .git/COMMIT_EDITMSG

Or create an alias for easy recovery:

bash
git config alias.recommit '!git commit -F "$(git rev-parse --git-dir)/COMMIT_EDITMSG" --edit'

# Then use:
git recommit
4Check hook script for errors

If you suspect the hook itself is broken, inspect it:

bash
# View the hook script
cat .git/hooks/commit-msg

# Or if using Husky
cat .husky/commit-msg

Common issues to look for:
- Wrong shebang line (should be #!/usr/bin/env sh or similar)
- Script not executable (chmod +x .git/hooks/commit-msg)
- Windows line endings causing "cannot execute binary file" error
- Missing dependencies (commitlint not installed)

Fix permissions:

bash
chmod +x .git/hooks/commit-msg
# Or for Husky
chmod +x .husky/commit-msg
5Fix Windows line ending issues

If you see "cannot execute binary file" or similar, the hook file likely has Windows (CRLF) line endings:

bash
# Check for CRLF endings
file .husky/commit-msg

# Convert to Unix line endings
sed -i 's/\r$//' .husky/commit-msg

# Or using dos2unix
dos2unix .husky/commit-msg

Ensure your editor and Git are configured for LF:

bash
git config --global core.autocrlf input
6Bypass the hook temporarily (if needed)

If you need to commit urgently and will fix the message later:

bash
git commit --no-verify -m "WIP: temporary commit"

Warning: Use this sparingly. The hook exists for a reason, and bypassing it regularly defeats its purpose. Some CI/CD pipelines will still validate commit messages and reject non-compliant ones.

7Verify commitlint configuration

If using commitlint, ensure it's properly configured:

bash
# Check if commitlint.config.js exists
cat commitlint.config.js

A basic configuration should look like:

javascript
module.exports = {
  extends: ['@commitlint/config-conventional'],
};

Test your message manually:

bash
echo "feat: test message" | npx commitlint

If commitlint isn't installed:

bash
npm install --save-dev @commitlint/cli @commitlint/config-conventional

Advanced notes

### Conventional Commits Specification

Conventional Commits is a lightweight convention for structuring commit messages. The full specification is:

bash
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Breaking changes can be indicated by:
- Adding ! after type/scope: feat!: drop support for Node 12
- Adding BREAKING CHANGE: in the footer

### Husky v9 Setup

For modern Husky (v9+) with commitlint:

bash
npm install --save-dev husky @commitlint/cli @commitlint/config-conventional
npx husky init
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

### Custom commit-msg Hooks

You can write custom validation in any language. Here's a simple shell example:

bash
#!/usr/bin/env sh
# .git/hooks/commit-msg

commit_msg=$(cat "$1")

# Require minimum length
if [ ${#commit_msg} -lt 10 ]; then
  echo "Error: Commit message must be at least 10 characters"
  exit 1
fi

# Require conventional commit format
if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?!?: .+"; then
  echo "Error: Commit message must follow Conventional Commits format"
  exit 1
fi

exit 0

### Pre-commit Framework

If using pre-commit framework with gitlint:

yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/jorisroovers/gitlint
    rev: v0.19.1
    hooks:
      - id: gitlint

### Debugging Hook Failures

To see exactly what's happening in your hook:

bash
# Add debug output to hook
set -x  # Add at top of script

Or run Git with trace output:

bash
GIT_TRACE=1 git commit -m "test message"

Frequently asked questions

What does "commit-msg hook failure" mean?
The commit-msg hook is a Git hook that runs after you write your commit message but before the commit is finalized. It receives the path to a temporary file containing your commit message as its only argument. If the hook script exits with a non-zero status code, Git aborts the commit entirely.
How do I fix "commit-msg hook failure"?
This error occurs when Git's commit-msg hook rejects your commit message. The hook validates message format (like conventional commits) and exits non-zero when validation fails. Fix by formatting your message correctly or bypassing the hook.
What causes "commit-msg hook failure"?
Commit message doesn't follow required format (e.g., Conventional Commits) Message is missing a required type prefix like feat:, fix:, or chore: Subject line exceeds maximum length limit (commonly 50-72 characters)
Is the "commit-msg hook failure" error serious?
It is a low-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading