Fixing Run-time error '28': Out of stack space in Excel VBA

intermediate📊 Microsoft Excel2026-06-23| Microsoft Excel (All versions), VBA (Visual Basic for Applications) on Windows and macOS.

Error Message

Run-time error '28': Out of stack space
#excel-vba#vba-errors#debugging#stack-overflow

What is a Stack Overflow in VBA?Ever had a macro suddenly freeze Excel, only to show a 'Run-time error 28' popup? This usually happens when your code gets stuck in a loop it can't escape. Think of the stack as a narrow pile of plates. Every time your code calls a new function, it adds a plate. If it keeps adding plates without ever finishing a task and removing one, the pile collapses. In VBA, the stack is a tiny slice of memory—usually around 1MB—dedicated to tracking active procedure calls.

Common CulpritsThe stack space is limited. You typically hit the ceiling in one of three ways:

  • Infinite Recursion: A function calls itself but lacks a "stop" button, leading to thousands of nested calls.- Event Cascading: An event like Worksheet_Change triggers a change that re-triggers the same event in a loop.- Overloaded Procedures: Using massive local arrays or calling hundreds of subroutines deep within each other.## Fix 1: Stop Event Cascading (The Most Likely Fix)Most developers run into Error 28 when writing code for worksheet events. Imagine you write a macro to automatically capitalize text. If the macro changes a cell, Excel notices that change and runs the macro again. This creates a feedback loop that exhausts the stack in milliseconds.

The Problematic Code```

' This triggers an endless loop immediately Private Sub Worksheet_Change(ByVal Target As Range) Target.Value = UCase(Target.Value) ' This change triggers the sub again! End Sub


### The SolutionTo stop the cycle, you must tell Excel to ignore its own changes temporarily. Use `Application.EnableEvents` to silence Excel while your code does its work.

Private Sub Worksheet_Change(ByVal Target As Range) On Error GoTo ErrorHandler

' Silence Excel events to prevent a loop
Application.EnableEvents = False

' Only run logic for specific cells (e.g., A1:A10)
If Not Intersect(Target, Me.Range("A1:A10")) Is Nothing Then
    Target.Value = UCase(Target.Value)
End If

CleanExit: ' ALWAYS turn events back on Application.EnableEvents = True Exit Sub

ErrorHandler: MsgBox "An error occurred: " & Err.Description Resume CleanExit End Sub


## Fix 2: Define a Base Case for RecursionRecursion is a powerful way to navigate folders or complex math, but it is risky. Every time a function calls itself, it consumes more of that 1MB stack. Without a clear exit condition, the code will dive deeper until it crashes.
### The Problematic Code```
Function CalculateFactorial(n As Long) As Long
    ' This will run until it hits the stack limit
    CalculateFactorial = n * CalculateFactorial(n - 1)
End Function

The SolutionEvery recursive function needs a "Base Case." This is a simple If statement that stops the function from calling itself once a goal is reached.

Function CalculateFactorial(n As Long) As Long
    ' Base Case: Stop once n hits 1
    If n <= 1 Then
        CalculateFactorial = 1
        Exit Function
    End If
    
    CalculateFactorial = n * CalculateFactorial(n - 1)
End Function

Fix 3: Use Loops Instead of Deep NestingIf your logic involves calling Sub A, which calls Sub B, which calls Sub C through a hundred levels, you are flirting with disaster. Large local variables, such as fixed-length strings or arrays with 10,000+ elements declared inside a Sub, also eat up stack space quickly.

  • Switch to Iteration: Use For...Next or Do...While loops instead of recursion. Loops use the heap (main system memory), which is gigabytes in size rather than the tiny 1MB stack.- Move Variables: Declare large arrays at the top of your module (Module-level) rather than inside a specific procedure to keep them off the stack.``` ' Iterative loops are much safer for the memory stack Function CalculateFactorialIterative(n As Long) As Long Dim result As Long, i As Long result = 1 For i = 1 To n result = result * i Next i CalculateFactorialIterative = result End Function

## How to Verify Your FixDon't just guess if the code is fixed. Use these debugging steps to be sure:
- **Step through with F8:** Press `F8` in the VBA Editor to run your code line-by-line. If you see the yellow highlight jumping back to the top of a sub unexpectedly, you've found an event loop.- **Monitor the Immediate Window:** Add `Debug.Print "Calling Sub at " & Now`. If your Immediate Window (Ctrl+G) fills with hundreds of lines in a second, your recursion is out of control.- **Stress Test:** If you use recursion, test it with a high value (like 500) to see if the stack can handle the depth without crashing.## Best Practices for Prevention- **Robust Error Handling:** If your code crashes while `EnableEvents` is False, Excel will stay "deaf" to all user actions. Always use a `CleanExit` label to re-enable events.- **Watch Your Depth:** If your logic requires nesting deeper than 20 or 30 levels, it is time to rethink your architecture.- **Limit Variable Scope:** Keep the stack lean by only declaring what you absolutely need inside your procedures.

Related Error Notes