The EAGAIN
error you encountered in your async code typically surfaces when a system call would block but the operation was requested in non-blocking mode. In your case:
{ [Error: spawn mediainfo EAGAIN]
code: 'EAGAIN',
errno: 'EAGAIN',
syscall: 'spawn mediainfo',
path: 'mediainfo',
spawnargs:
[ '--Output=XML',
'/home/buzut/testMedia' ],
cmd: 'mediainfo --Output=XML /home/buzut/testMedia' }
This suggests your process hit a resource limitation during child process creation. The most likely culprits are process count (nproc
) or memory constraints.
Let's break down the critical limits and their system impacts:
Process-Related Limits
- nproc (-u): Max number of processes per user. Exceeding this causes fork() failures.
- maxlogins: Limits concurrent user sessions.
- priority (-e): Process scheduling priority (-20 to 19).
Memory Constraints
- memlock (-l): Limits
mlock()
operations (critical for real-time apps). - as (-v): Total virtual memory address space.
- rss: Physical memory usage limit.
File System Limitations
- nofile (-n): Open file descriptors (affects databases/servers).
- locks (-x): File locks (relevant for concurrent access).
- fsize (-f): Maximum file creation size.
Your current limits show:
max user processes (-u) 127698
open files (-n) 64000
These seem generous, but let's verify actual usage:
# Check current process count
ps -u $(whoami) | wc -l
# Check open files
lsof -u $(whoami) | wc -l
Temporary Adjustment
# Increase process limit for current session
ulimit -u 200000
Permanent Configuration
Edit /etc/security/limits.conf
:
buzut soft nproc 200000
buzut hard nproc 200000
Node.js Specific Fixes
For async process spawning:
const { spawn } = require('child_process');
const child = spawn('mediainfo', ['--Output=XML', filePath], {
stdio: 'inherit',
detached: true // Prevents EAGAIN in busy systems
});
Implement resource tracking in your app:
const fs = require('fs');
setInterval(() => {
fs.readFile('/proc/${process.pid}/limits', (err, data) => {
console.log('Current limits:', data.toString());
});
}, 5000);
- Verify system-wide limits with
cat /proc/sys/kernel/threads-max
- Check for cgroup restrictions (common in containers)
- Monitor
dmesg
for OOM killer activity - Test with stripped-down process spawning
When dealing with async operations in Linux, you might encounter the frustrating EAGAIN
error (Error Code 11), which indicates a temporary resource unavailability. This often stems from misconfigured ulimit
settings that restrict process capabilities.
Let's examine the most impactful settings for async operations:
// Key parameters affecting async operations
nofile - Maximum open files (default often too low for servers)
nproc - Maximum processes per user (critical for Node.js clusters)
memlock - Locked memory (affects some database operations)
msgqueue - POSIX message queues (important for IPC)
stack - Thread stack size (can cause crashes if too small)
Your specific error suggests the system couldn't spawn a new process when executing mediainfo
. This typically relates to either:
- Reaching the user process limit (
nproc
) - Hitting the system-wide process limit
- Insufficient memory allocation
Check current limits with:
// View current limits
$ ulimit -a
// Check system-wide limits
$ cat /proc/sys/kernel/threads-max
$ cat /proc/sys/kernel/pid_max
$ cat /proc/sys/vm/max_map_count
For Node.js applications handling many concurrent operations:
# /etc/security/limits.conf
* soft nofile 100000
* hard nofile 100000
* soft nproc 20000
* hard nproc 20000
* soft memlock unlimited
* hard memlock unlimited
# sysctl adjustments
vm.max_map_count=1048576
kernel.pid_max=4194304
Implement retry logic for robust operation:
const { spawn } = require('child_process');
const retry = require('async-retry');
async function runMediaInfo(file) {
return await retry(
async (bail) => {
const proc = spawn('mediainfo', [
'--Output=XML',
file
]);
// Handle process events and errors
// ...
},
{
retries: 3,
minTimeout: 100
}
);
}
Regularly check resource usage:
# Count open files per process
$ lsof | wc -l
# Check process count per user
$ ps -u youruser | wc -l
# Monitor memory usage
$ free -h
$ cat /proc/meminfo
For containerized environments:
- Docker: Use
--ulimit
flags - Kubernetes: Configure
securityContext
- Systemd: Set
Limit*
directives in service files