Kernel#fail

fail([exception [, msg [, backtrace]]]) -> never
Returns: never · Updated March 13, 2026 · Kernel Methods
exceptions errors control-flow

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

ParameterTypeDefaultDescription
exceptionExceptionRuntimeErrorAn exception instance or class to raise
msgStringexception’s default messageThe error message
backtraceArraycaller backtraceCustom 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

ExceptionWhen It Occurs
RuntimeErrorDefault when no exception specified
ArgumentErrorInvalid arguments passed
Any specifiedWhen 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 fail when signaling an actual failure condition — a guard clause that halts execution because something is wrong
  • Use raise for 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

See Also