# Can I make stack overflow warnings fatal?

**URL:** <https://discourse.julialang.org/t/can-i-make-stack-overflow-warnings-fatal/139579>\
**Category:** General Usage\
**Created:** [September 21, 2026, 9:59am UTC](https://discourse.julialang.org/t/can-i-make-stack-overflow-warnings-fatal/139579 "2026-09-21T09:59:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![piechologist](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piechologist/32/27662_2.png) [@piechologist](https://discourse.julialang.org/u/piechologist)\
**Post date:** [September 21, 2026, 9:59am UTC](https://discourse.julialang.org/t/can-i-make-stack-overflow-warnings-fatal/139579/1 "2026-09-21T09:59:20Z")

</div>

I saw my Julia process writing `Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable.` to stderr after failed C-calls. The process is running as a systemd unit. Currently, I’m running a journalctl watcher that kills the Julia process on such rare occasions.

Is there a way to tell the Julia runtime to throw immediately instead of just writing a warning?

I think I’ve mitigated the root cause for the SO — I’m only asking about Julia exiting automatically.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [September 21, 2026, 12:12pm UTC](https://discourse.julialang.org/t/can-i-make-stack-overflow-warnings-fatal/139579/2 "2026-09-21T12:12:03Z")

</div>

I see “fixed on master” here, so this might apply (on second thought it likely doesn’t):

> <https://github.com/julialang/julia/issues/60265>
>
> In julia 1.12.2 (Linux), I have this warning:
> 
> \`\`\`julia
> @inline \_\_tf(result, tim…e) = result
> @inline function \_\_tf(result, time::T, d1, dn...) where {T}
> return if d1 == 0
> \_\_tf((result..., T(0)), 0, dn...)
> else
> p, time2 = divrem(time, d1, RoundDown)
> \_\_tf((result..., T(p)), time2, dn...)
> end
> end
> 
> @inline function \_timetuple2(time, divi)
> return \_\_tf((), time, divi...)
> end
> 
> function timetuplefrac2(time)
> # 10 element tuple
> divi = (1.0f0, 0.041666668f0, 0.00069444446f0, 1.1574074f-5, 1.1574074f-8,
> 1.1574074f-11, 1.1574073f-14, 1.1574074f-17,
> 1.15740735f-20,
> 1.1574074f-23,
> )
> 
> return \_timetuple2(time, divi)
> end
> 
> time = 51545.0f0
> timetuplefrac2(time)
> \`\`\`
> 
> The full output is:
> \`\`\`
> julia\> timetuplefrac2(time)
> Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable.
> Internal error: during type inference of
> timetuplefrac2(Float32)
> Encountered stack overflow.
> This might be caused by recursion over very long tuples or argument lists.
> (51545.0f0, 0.0f0, 0.0f0, 0.0f0, 0.0f0, 0.0f0, 0.0f0, 0.0f0, 0.0f0, 0.0f0)
> 
> \`\`\`
> 
> It used to work in julia 1.11 without this warning.
> I am wondering if a 10-element tuple, is already considered a very long tuple?
> Or what is the maximum number of inlining allowed?
> 
> Ref: https://github.com/JuliaGeo/CFTime.jl/issues/63

I’m looking into this, but need to run right now, what I found:

> [@StackOverflowError after only 14 calls to the same function?](https://discourse.julialang.org/t/stackoverflowerror-after-only-14-calls-to-the-same-function/133693):
>
> How many times does a function have to be called before a StackOverflowError is triggered? When I try with a simple recursive function call, it seems to be about 80,000. However, in my program, I have a function that is not recursive, but happens to call itself quite a few times - it is doing some post-processing analysis where one variable depends on others that depend on others, etc. but there is no cyclic dependency. The stacktrace below shows the error, but there are no ‘repeated’ entries, a…

---

<div class="post-metadata">

**Author:** ![piechologist](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piechologist/32/27662_2.png) [@piechologist](https://discourse.julialang.org/u/piechologist)\
**Post date:** [September 21, 2026, 2:14pm UTC](https://discourse.julialang.org/t/can-i-make-stack-overflow-warnings-fatal/139579/3 "2026-09-21T14:14:52Z")

</div>

Thank you, I think the GitHub issue and the fix on master is about a type inference that may cause a stack overflow, not about the SO detection/warning.

The discourse topic you linked is interesting as it throws `ERROR: LoadError: StackOverflowError:`. I’ve never seen a StackOverflowError and a stacktrace on my workload, there was just the warning I mentioned above, a log message with a huge blob of C pointers, and the program kept running before crashing subsequently.

Obviously, there are some (many?) conditions that can trigger a SO and throwing would be a better fit for a long-running production process.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [September 21, 2026, 2:26pm UTC](https://discourse.julialang.org/t/can-i-make-stack-overflow-warnings-fatal/139579/4 "2026-09-21T14:26:14Z")

</div>

Stack overflows _do_ throw! But it sounds like you’re catching it in a `try` block. You can make it fatal just by checking the catched exception.

```julia-auto
julia> f() = g()
f (generic function with 1 method)

julia> g() = f()
g (generic function with 1 method)

julia> try
           g()
       catch
       end
Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable.

julia> try
           g()
       catch ex
           ex isa StackOverflowError && rethrow()
       end
Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable.
ERROR: StackOverflowError:

```

---

<div class="post-metadata">

**Author:** ![piechologist](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piechologist/32/27662_2.png) [@piechologist](https://discourse.julialang.org/u/piechologist)\
**Post date:** [September 21, 2026, 4:01pm UTC](https://discourse.julialang.org/t/can-i-make-stack-overflow-warnings-fatal/139579/5 "2026-09-21T16:01:15Z")

</div>

> [@mbauman](#):
>
> `StackOverflowError`

That’s it! I have a call to `Downloads.request(... throw = false)` and a check for `Downloads.RequestError` only. The warnings I saw originated from the surrounding function. ~~Rethrowing the other error types should fix it.~~ **see the next post below**

The stack overflows happened rarely and in a live API only. That made it difficult to track them back to libcurl. Good catch, thank you very much!

---

<div class="post-metadata">

**Author:** ![piechologist](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piechologist/32/27662_2.png) [@piechologist](https://discourse.julialang.org/u/piechologist)\
**Post date:** [September 25, 2026, 1:32pm UTC](https://discourse.julialang.org/t/can-i-make-stack-overflow-warnings-fatal/139579/6 "2026-09-25T13:32:14Z")

</div>

I was wrong about rethrowing. The `throw = false` kwarg returns only a `Downloads.RequestError`. All other exceptions are thrown anyway.

The root cause seems to be more troublesome: in some circumstances, a `try`/`catch` block does not catch a `StackOverflowError`. The error is printed directly to stderr but the process continues running in a corrupted state.

**EDIT: Indeed, asynchronous SOs cannot be caught reliably, see the GH issue [What to do about asynchronous exceptions](https://github.com/JuliaLang/julia/issues/52291).**

* * *

Excuse me for pasting a Claude generated blob; I wasn’t able to track this down by myself:

## `StackOverflowError` skips `try`/`catch`/`finally` in compiled frames

I hit this chasing why a `catch` around some network code never fired on a stack overflow,  
and the behaviour turned out to be more general than I expected: **a `StackOverflowError`  
does not run `catch` _or_ `finally` in a compiled frame.** It unwinds past them to the  
nearest interpreted handler — top level, typically — or, if it is inside a `Task`, it just  
fails the task. No handler in between gets a chance to run.

### MWE

```julia
f(n) = f(n + 1) + 1 # exhaust the stack

const ran = Ref(:neither)
g() = try f(0) catch; ran[] = :catch finally ran[] = :finally end

# 1. try/catch/finally in a compiled frame
esc = try g() catch e; typeof(e) end
println("1. compiled handler ran : ", ran[])
println(" escaped to top level : ", esc)

# 2. the same compiled handler, in a task
ran[] = :neither
t = @async g()
wait(t; throw = false)
println("2. compiled handler ran : ", ran[])
println(" istaskfailed : ", istaskfailed(t), ", t.result::", typeof(t.result))

# 3. the same try/catch interpreted, in a task
body = :(try f(0) catch e; println("3. interpreted catch ran: ", typeof(e)) end)
t = @async Core.eval(Main, body)
wait(t; throw = false)
println(" istaskfailed : ", istaskfailed(t))

```

Output (stdout):

```julia-auto
1. compiled handler ran : neither
   escaped to top level : StackOverflowError
2. compiled handler ran : neither
   istaskfailed : true, t.result::StackOverflowError
3. interpreted catch ran: StackOverflowError
   istaskfailed : false

```

and on stderr, three raw writes from the runtime:

```julia-auto
Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable.

```

Case 1 is the surprise: `g`’s `catch` never runs, and neither does its `finally`, yet the  
error is perfectly catchable one frame further out, at top level. Case 2 is the same thing  
inside a task — the task fails, and the only in-process way to see it is at the join  
(`istaskfailed(t)` / `t.result`). Case 3 is the control: exactly the same `try`/`catch`,  
evaluated by the interpreter, catches it even inside a task.

The compiled-vs-interpreted reading is confirmed by `--compile=min`, where every handler in  
the same script runs normally:

```julia-auto
1. compiled handler ran : finally
   escaped to top level : catch
2. compiled handler ran : finally
   istaskfailed : false, t.result::Symbol

```

* * *

Confirmed for Julia 1.13.0 on both macOS 27 and CentOS Stream 10.
