Kernel#fail
fail([exception [, msg [, backtrace]]]) -> never never · Updated March 13, 2026 · Kernel Methods fail is a Ruby keyword that raises an exception. It is functionally identical to raise — the two are exact aliases. The only difference is stylistic: some developers prefer fail when indicating a failure condition, while raise is more commonly used for general exception raising.
Syntax
fail
fail exception_object
fail "Error message"
fail ExceptionClass, "Error message"
fail ExceptionClass, "Error message", backtrace_array
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
exception | Exception | RuntimeError | An exception instance or class to raise |
msg | String | exception’s default message | The error message |
backtrace | Array | caller backtrace | Custom backtrace information |
When passed a class (e.g., fail RuntimeError, "message"), Ruby instantiates it with the message.
Examples
Basic usage
fail "Something went wrong"
# => RuntimeError: Something went wrong
Raising a specific exception type
fail ArgumentError, "Invalid input"
# => ArgumentError: Invalid input
Raising a custom exception instance
class CustomError < StandardError; end
fail CustomError.new("Custom failure")
# => CustomError: Custom failure
Using fail in begin/rescue blocks
begin
fail "Intentional failure"
rescue RuntimeError => e
puts "Caught: #{e.message}"
end
# Output: Caught: Intentional failure
Common Patterns
Guard clauses with fail
def process(data)
fail "Data cannot be nil" if data.nil?
# ... rest of method
end
Fail vs raise — stylistic choice
# Both are identical — pick whichever reads better in context
raise "Connection refused" # generic
fail "Connection refused" # suggests operational failure
Errors
| Exception | When It Occurs |
|---|---|
RuntimeError | Default when no exception specified |
ArgumentError | Invalid arguments passed |
| Any specified | When that specific exception type is raised |
When to Use fail
The fail keyword behaves identically to raise, so your choice should be based on code clarity and team conventions:
- Use
failwhen signaling an actual failure condition — a guard clause that halts execution because something is wrong - Use
raisefor general exception raising — especially when re-raising or raising from within rescue blocks
# Using fail for failure conditions
def withdraw(amount)
fail "Insufficient funds" if amount > balance
# ... process withdrawal
end
# Using raise more generally
def parse(input)
raise "Invalid format" unless valid?(input)
# ... parse
rescue
raise # re-raising preserves the original exception
end
The Ruby style guide does not enforce either form. Many projects pick one and stick with it consistently throughout the codebase.
Backtrace Manipulation
You can provide a custom backtrace array as the third argument. This is rarely needed but useful for testing or wrapping external code:
custom_backtrace = ["my_file.rb:10:in 'method'", "my_file.rb:20:in 'caller'"]
fail "Custom error", custom_backtrace