Fixing up nginx file opening permissions

Got this error message on startup of nginx.

nginx: [warn] 4096 worker_connections exceed open file resource limit: 1024

There are a lot of places you can change this value so it gets a bit confusing. It could be the user that nginx is running under, (usually www-data) or the process, or it could be set in systemd init file or in security/limits.conf … OK, so we'll run a script to gather the info

#!/bin/bash

# --- Configuration ---
NGINX_CONF="/etc/nginx/nginx.conf"
NGINX_SERVICE="nginx.service"
LIMITS_CONF="/etc/security/limits.conf"
SYSCTL_CONF="/etc/sysctl.conf"
# --- End Configuration ---

echo "#################################################################"
echo "# NGINX ULIMIT (MAX OPEN FILES) CHECKER"
echo "#################################################################"

# 1. Find the NGINX User
NGINX_USER=$(grep -E '^\s*user\s+' $NGINX_CONF | awk '{print $2}' | sed 's/;//' | head -n 1)
if [[ -z "$NGINX_USER" ]]; then
    NGINX_USER="www-data" # Common default user if not explicitly set
fi
echo -e "\n[1] NGINX RUNNING USER: ${NGINX_USER}"

# 2. Get NGINX Process Limits
echo -e "\n[2] CURRENT NGINX WORKER PROCESS LIMITS (/proc/<pid>/limits)"
NGINX_PID=$(pgrep -u "$NGINX_USER" nginx | head -n 1)
if [[ -n "$NGINX_PID" ]]; then
    cat "/proc/$NGINX_PID/limits" | grep "Max open files"
else
    echo "NGINX worker process is not currently running under user '$NGINX_USER'."
fi

# 3. Check NGINX Configuration Directives
echo -e "\n[3] NGINX CONFIGURATION CHECK (${NGINX_CONF})"
NGINX_RBLIMIT=$(grep -E '^\s*worker_rlimit_nofile\s+' $NGINX_CONF | awk '{print $2}' | sed 's/;//' | head -n 1)
NGINX_CONNECTIONS=$(grep -E '^\s*worker_connections\s+' $NGINX_CONF | awk '{print $2}' | sed 's/;//' | head -n 1)

if [[ -n "$NGINX_RBLIMIT" ]]; then
    echo -e "   - worker_rlimit_nofile: \t**$NGINX_RBLIMIT**"
else
    echo -e "   - worker_rlimit_nofile: \tNot set (NGINX inherits OS limit)"
fi

if [[ -n "$NGINX_CONNECTIONS" ]]; then
    echo -e "   - worker_connections: \t**$NGINX_CONNECTIONS**"
else
    echo -e "   - worker_connections: \tNot set (Defaults to 512 or 1024)"
fi

# 4. Check systemd Service Unit Limit (Most modern Linux systems)
echo -e "\n[4] SYSTEMD SERVICE UNIT LIMIT (${NGINX_SERVICE})"
SYSTEMD_LIMIT=$(systemctl show $NGINX_SERVICE --property LimitNOFILE | awk -F'=' '{print $2}')
if [[ -n "$SYSTEMD_LIMIT" ]]; then
    echo -e "   - LimitNOFILE (systemd): \t**$SYSTEMD_LIMIT**"
else
    echo "   - LimitNOFILE (systemd): \tNot explicitly set (Inherits from system defaults/limits.conf)"
fi

# 5. Check User Limits (limits.conf)
echo -e "\n[5] USER LIMITS CONFIGURATION (${LIMITS_CONF})"
USER_LIMITS=$(grep -E "^$NGINX_USER\s+(soft|hard)\s+nofile" $LIMITS_CONF)
ALL_USER_LIMITS=$(grep -E "^\*\s+(soft|hard)\s+nofile" $LIMITS_CONF)

if [[ -n "$USER_LIMITS" ]]; then
    echo -e "   - Limits for $NGINX_USER:\n$USER_LIMITS"
elif [[ -n "$ALL_USER_LIMITS" ]]; then
    echo -e "   - General limits (*):\n$ALL_USER_LIMITS"
else
    echo "   - No explicit nofile limits found for '$NGINX_USER' or '*'."
fi

# 6. Check System-Wide Kernel Limit
echo -e "\n[6] SYSTEM-WIDE KERNEL LIMIT (fs.file-max)"
KERNEL_MAX=$(cat /proc/sys/fs/file-max)
echo -e "   - fs.file-max (Kernel): \t**$KERNEL_MAX**"

echo "#################################################################"

OK, so that gives us the output

#################################################################
# NGINX ULIMIT (MAX OPEN FILES) CHECKER
#################################################################

[1] NGINX RUNNING USER: www-data

[2] CURRENT NGINX WORKER PROCESS LIMITS (/proc/<pid>/limits)
Max open files            1024                 524288               files     

[3] NGINX CONFIGURATION CHECK (/etc/nginx/nginx.conf)
   - worker_rlimit_nofile: 	Not set (NGINX inherits OS limit)
   - worker_connections: 	**4096**

[4] SYSTEMD SERVICE UNIT LIMIT (nginx.service)
   - LimitNOFILE (systemd): 	**524288**

[5] USER LIMITS CONFIGURATION (/etc/security/limits.conf)
   - Limits for www-data:
www-data         hard    nofile          65536
www-data         soft    nofile          65536

[6] SYSTEM-WIDE KERNEL LIMIT (fs.file-max)
   - fs.file-max (Kernel): 	**9223372036854775807**
#################################################################

So we need to alter the low value for the nginx worker process, currently at 1024

Insert this line near the top of /etc/nginx/nginx.conf file, before the events {} section.

worker_rlimit_nofile 65536; 

And restart nginx. Now we see

[2] CURRENT NGINX WORKER PROCESS LIMITS (/proc/<pid>/limits)
Max open files            65536                65536                files     

[3] NGINX CONFIGURATION CHECK (/etc/nginx/nginx.conf)
   - worker_rlimit_nofile: 	**65536**
   - worker_connections: 	**4096**

Leave a Comment