Skip to content

πŸ› [Bug]: app.init() holds mutex without defer β€” panic causes permanent deadlockΒ #4328

@pageton

Description

@pageton

Bug Description

app.init() acquires app.mutex.Lock() at line 1446 and releases it manually at line 1487 β€” without using defer. If any code between Lock and Unlock panics (e.g., initServices(), Views.Load()), the mutex is never released, causing a permanent deadlock on any subsequent app.mutex acquisition.

How to Reproduce

Steps to reproduce the behavior:

  1. Register a custom Views implementation that panics on Load()
  2. Call any method that triggers app.init() (e.g., app.Listen(), app.Test())
  3. The panic is recovered by the HTTP server, but app.mutex remains locked
  4. Any subsequent call to app.Listen(), app.AddRoute(), etc. deadlocks permanently

Affected Code

app.go:1446-1487:

func (app *App) init() *App {
    app.mutex.Lock()      // line 1446 β€” no defer

    app.initServices()    // line 1450 β€” can panic
    if err := app.config.Views.Load(); err != nil { // line 1454
        log.Warnf(...)
    }
    // ... 30+ lines of server configuration ...

    app.mutex.Unlock()    // line 1487 β€” never reached on panic
}

Expected Behavior

Use defer app.mutex.Unlock() immediately after Lock(), or wrap the critical section in a named function with defer.

Fiber Version

v3 (latest main branch)

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions