Skip to content

[0.41.x / 0.42.4] Heap corruption (malloc(): corrupted top size) causes SIGABRT/core dump and container restart #587

Description

@DevlTz

Summary

Hi @matteius!

After upgrading my Docker deployment to LightNVR 0.41.4, I started noticing occasional web UI stalls where refreshing the page would remain on the loading screen for an unusually long time.

Initially, I thought this was only a frontend/web issue. However, after checking the Docker state, LightNVR logs, and systemd coredumps, I confirmed that the main LightNVR process is actually aborting and being restarted by Docker.

The most relevant error is:

malloc(): corrupted top size

followed by:

Aborted (core dumped) /bin/lightnvr -c /etc/lightnvr/lightnvr.ini

A preserved systemd core dump confirms that LightNVR terminated with SIGABRT (signal 6).


Environment

  • LightNVR: 0.41.4
  • Build date reported by LightNVR: 2026-09-02
  • Deployment: Docker
  • Docker restart policy: unless-stopped
  • Approximately 54 configured streams
  • max_streams=60
  • API/object detection enabled
  • Detection interval: mostly 40s
  • External detection API configured

Docker reported:

Status=running
Running=true
Restarting=false
ExitCode=0
OOMKilled=false
RestartCount=1

System resources were also checked after the incident:

LightNVR memory usage: ~1.67 GiB
Container memory limit: 64 GiB
Host available memory: ~74 GiB
Root filesystem usage: ~43%
Recording/data filesystem usage: ~42%

The following command returned no OOM, killed-process, or kernel segfault events:

dmesg -T | grep -Ei 'oom|out of memory|killed process|segfault'

So this does not currently appear to be caused by OOM or disk exhaustion.


Observed sequence before the crash

Shortly before the process aborted, LightNVR started reporting that its own health endpoint was becoming slow:

[2026-09-03 14:07:05.863] [ERROR] [HealthCheck] Health check curl failed: Timeout was reached
[2026-09-03 14:07:05.881] [WARN] [HealthCheck] Health check failed (consecutive failures: 4)
[2026-09-03 14:07:05.881] [WARN] [HealthCheck] Health endpoint remains slow but the web event loop is alive; leaving the listener intact and retrying without an in-process restart

This matches what I was seeing from the browser: occasionally an F5/reload would remain on the LightNVR loading screen for much longer than usual.

Detection activity continued during this period.

For example:

[2026-09-03 14:07:10.077] [INFO] [Detection] Running detection (interval=40s, elapsed=100s, model=api-detection)

[2026-09-03 14:07:10.296] [WARN] [Detection] API Detection (snapshot): Failed to get snapshot from go2rtc for stream [redacted]

[2026-09-03 14:07:10.296] [INFO] [Detection] go2rtc snapshot unavailable, falling back to frame decode

[2026-09-03 14:07:10.296] [ERROR] [Detection] CURL request failed for snapshot: Timeout was reached

A few moments later, the following appeared:

malloc(): corrupted top size

The main LightNVR process then aborted:

/bin/start.sh: line 10: 58 Aborted (core dumped) /bin/lightnvr -c /etc/lightnvr/lightnvr.ini
Cleaning up processes...

Immediately afterwards, container initialization started again.


Docker restart behavior

The container uses the following restart policy:

RestartPolicy={"Name":"unless-stopped","MaximumRetryCount":0}

Because of this, Docker automatically starts LightNVR again after the process aborts.

This initially made the problem appear to be only a temporary web UI outage.

The observed behavior from the operator side is approximately:

  1. Web UI becomes slow.
  2. Page refresh remains on the loading screen.
  3. Web UI becomes temporarily unavailable.
  4. LightNVR process aborts.
  5. Docker restarts the container.
  6. LightNVR eventually becomes available again.

Core dump confirmation

The host is configured to use systemd-coredump, and the crash was successfully preserved.

coredumpctl info reports:

PID: 1387032 (lightnvr)
UID: 0 (root)
GID: 0 (root)
Signal: 6 (ABRT)
Timestamp: Thu 2026-09-03 14:07:11 -03
Command Line: /bin/lightnvr -c /etc/lightnvr/lightnvr.ini
Executable: /usr/bin/lightnvr
Message: Process 1387032 (lightnvr) of user 0 dumped core.

The basic stack trace currently provided by coredumpctl is:

Stack trace of thread 165:
#0  0x00007f2928fbffac n/a (/usr/lib/x86_64-linux-gnu/libc.so.6)
#1  0x0000000000000000 n/a (n/a)

The actual core dump has been preserved locally.

I am intentionally not attaching the raw core dump publicly, since process memory may contain RTSP URLs, camera credentials, internal addresses, configuration data, or other sensitive information.

I can provide a sanitized GDB backtrace if that would help investigate the issue.


Another crash on the same day

There is also another preserved LightNVR SIGABRT core dump from earlier on the same day:

PID: 3428740 (lightnvr)
Signal: 6 (ABRT)
Timestamp: Thu 2026-09-03 09:03:31 -03
Command Line: /bin/lightnvr -c /etc/lightnvr/lightnvr.ini
Executable: /usr/bin/lightnvr

I cannot yet confirm whether this earlier crash has the same root cause, so I am mentioning it only as additional context.

The host also contains historical LightNVR coredump entries from older deployments, mostly SIGABRT (signal 6) with a few SIGSEGV (signal 11) occurrences.

Because of that, I do not want to assume that the underlying memory issue necessarily originated in 0.41.4.

However, the crash described in this issue definitely occurred while running LightNVR 0.41.4, and the log explicitly reported:

malloc(): corrupted top size

Actual behavior

During normal operation, the LightNVR process eventually reaches:

malloc(): corrupted top size

and terminates with:

SIGABRT / core dump

Docker then automatically restarts the entire LightNVR container.


Expected behavior

Failures such as:

  • slow or unavailable cameras;
  • go2rtc snapshot timeouts;
  • detection API timeouts;
  • slow health endpoints;
  • detection worker delays;

should be isolated and handled gracefully without corrupting the LightNVR process heap or terminating the complete NVR process.


Impact

The crash affects the entire LightNVR process, rather than only the individual camera, stream, detection request, or worker experiencing a problem.

For an NVR deployment, this causes temporary service interruption.

Because Docker automatically restarts the container with restart: unless-stopped, the underlying native process crash can easily be hidden from the operator.

Without checking the logs, RestartCount, or system coredumps, the incident initially looks like a temporary web UI/loading problem.


Additional observations

Around the same period, some detection jobs configured with a 40s interval were executing with considerably larger elapsed times.

Examples:

interval=40s, elapsed=80s
interval=40s, elapsed=88s
interval=40s, elapsed=100s

There were also occasional go2rtc snapshot timeouts:

[ERROR] [Detection] CURL request failed for snapshot: Timeout was reached

[WARN] [Detection] API Detection (snapshot): Failed to get snapshot from go2rtc

[INFO] [Detection] go2rtc snapshot unavailable, falling back to frame decode

The fallback mechanism usually continued working correctly.

I don't know whether these conditions are related to the heap corruption, but I am including them because they were occurring shortly before the crash.


Reproduction

I do not yet have a deterministic minimal reproducer.

The issue occurred during normal operation of a relatively large deployment with approximately 54 configured streams and API detection enabled.

The observed sequence was:

Normal operation
        ↓
Web / health endpoint becomes slow
        ↓
Multiple health check timeouts
        ↓
Concurrent detection activity
        ↓
Some go2rtc snapshot timeouts
        ↓
malloc(): corrupted top size
        ↓
SIGABRT + core dump
        ↓
Docker restarts LightNVR
        ↓
Service becomes available again

I will continue monitoring the deployment and can provide additional logs, another crash occurrence, or a sanitized GDB backtrace if useful.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions