Ubuntu Nginx/Apache Log Guide: access/error Log Location and Analysis

Nginx/Apache Log Investigation - access/error

What You'll Learn

  • Where Nginx/Apache log files are located in Ubuntu
  • How to isolate causes for "500/502/503/504", "403", "404" from logs
  • A systematic approach to log investigation (order, filtering, reproduce, verify)
  • Understanding that log bloat can cause disk issues

Quick Summary

When web is broken, follow this order:

  1. Check service status: systemctl status nginx|apache2
  2. Check error log: tail -n 200 .../error.log
  3. Find failing request in access log: grep " 500 " .../access.log
  4. Reproduce and watch logs in real-time (most powerful)
  5. 502/503 means check upstream (app side)

Table of Contents

  1. Check Which Server Is Running
  2. Log Locations (Ubuntu Typical Paths)
  3. First Check "error log"
  4. Find Failing Request in access log
  5. Status Code Isolation Guide
  6. Finding Non-Default Log Locations
  7. Filtering Tips
  8. Common error.log Messages
  9. Things to Avoid

Prerequisites

  • OS: Ubuntu
  • Web Server: Nginx or Apache
  • sudo access
  • Fixed procedures for beginners to not get lost

1. Check Which Server Is Running (Nginx? Apache?)

Skip if you already know.

1-1. Check by Service Status

$ sudo systemctl status nginx
$ sudo systemctl status apache2
  • nginx is active → Check Nginx logs
  • apache2 is active → Check Apache logs
  • Both active → Probably reverse proxy setup (check front-end logs first)

1-2. Check by Port (Supplemental)

$ sudo ss -lntp | grep ':80 '
$ sudo ss -lntp | grep ':443 '

2. Log Locations (Ubuntu Typical Paths)

Usually here on Ubuntu:

2-1. Nginx

  • error log: /var/log/nginx/error.log
  • access log: /var/log/nginx/access.log
$ ls -la /var/log/nginx

2-2. Apache (apache2)

  • error log: /var/log/apache2/error.log
  • access log: /var/log/apache2/access.log
$ ls -la /var/log/apache2

3. First Check "error log" (Fastest Path)

Access log shows "what happened", but root cause (stack trace/config error/upstream death) appears in error.log.

3-1. View Last 200 Lines (First Step)

# Nginx
$ sudo tail -n 200 /var/log/nginx/error.log

# Apache
$ sudo tail -n 200 /var/log/apache2/error.log

3-2. Real-time Tracking While Reproducing (Most Powerful)

# Nginx
$ sudo tail -f /var/log/nginx/error.log

# Apache
$ sudo tail -f /var/log/apache2/error.log

Keep this open, reproduce with browser/curl in another tab, and you'll find the cause fast. "Checked logs but couldn't understand" usually means not reproducing simultaneously.

4. Find Failing Request in access log

4-1. Find 500 Errors Only

$ sudo grep " 500 " /var/log/nginx/access.log | tail -n 50

4-2. Find 404 Errors Only

$ sudo grep " 404 " /var/log/nginx/access.log | tail -n 50

4-3. Find Specific Path Only (e.g., /api/)

$ sudo grep " /api/" /var/log/nginx/access.log | tail -n 50

5. Status Code Isolation Guide

5-1. 500 (Internal Server Error)

  • App internal error (PHP/Node/Ruby, etc.)
  • Config mistake (FastCGI settings, etc.)
  • Permission/path (Permission denied) possible

Next: error.log (priority), app logs, journalctl -u

5-2. 502 / 503 / 504 (Bad Gateway / Service Unavailable / Gateway Timeout)

  • Nginx/Apache can't connect to upstream / slow response / dead

Next step:

$ nc -vz 127.0.0.1 3000
$ curl -I http://127.0.0.1:3000

5-3. 403 (Forbidden)

  • Basic auth, IP restriction, WAF, directory permission, file permission

Next: error.log will show "permission denied" or "client denied"

5-4. 404 (Not Found)

  • Routing / file doesn't exist
  • SPA rewrite config missing

6. Finding Non-Default Log Locations

6-1. Nginx: Dump All Config

$ sudo nginx -T 2>&1 | grep -E "access_log|error_log" | head -n 50

6-2. Apache: Check Config

$ sudo apache2ctl -S

7. Filtering Tips for Faster Investigation

7-1. Want to See Only What's Happening Now

Best: "reproduce → tail -f"

7-2. Filter by Keyword (e.g., upstream)

$ sudo grep -i "upstream" /var/log/nginx/error.log | tail -n 50

8. Common error.log Messages

8-1. connect() failed (111: Connection refused) while connecting to upstream

Meaning: Upstream isn't listening / down

$ nc -vz 127.0.0.1 <upstream-port>
$ sudo systemctl status <app-service>

8-2. upstream timed out (110: Connection timed out)

Meaning: Upstream is slow/congested (load, DB, I/O, etc.)

8-3. permission denied

Meaning: File/directory permission issue, possibly SELinux/AppArmor

8-4. client intended to send too large body

Meaning: Upload size limit (nginx client_max_body_size, etc.)

9. Things to Avoid

Don't: Spam restart Without Checking Logs

Restarting without logs just hides the cause and wastes time. Check error.log / journalctl first.

Don't: Only Check access.log and Stop There

Root cause is usually in error.log. Access log is for "which request failed".

Don't: Ignore Log Bloat

More traffic = more logs. Can lead to disk full (No space left). Monitor disk and configure log rotation (logrotate).

Copy-Paste Template (Nginx Example)

# Service status
sudo systemctl status nginx

# Error (check this first)
sudo tail -n 200 /var/log/nginx/error.log

# Real-time tracking while reproducing (most powerful)
sudo tail -f /var/log/nginx/error.log

# Find failing requests
sudo grep " 500 " /var/log/nginx/access.log | tail -n 50
sudo grep " 502 " /var/log/nginx/access.log | tail -n 50
sudo grep " 403 " /var/log/nginx/access.log | tail -n 50
sudo grep " 404 " /var/log/nginx/access.log | tail -n 50

Summary

  • Check error.log first, then access.log
  • Reproduce + tail -f is the fastest path
  • 502/503/504 → investigate upstream (app). Use port connectivity checks.
  • Logs consume disk. Can cause "No space left" issues.

Test Environment

Commands in this article were tested on Ubuntu 24.04 LTS / bash 5.2.

Next Reading