{"id":2956,"date":"2025-12-05T18:23:34","date_gmt":"2025-12-05T15:23:34","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/how-to-read-web-server-logs-to-diagnose-4xx-5xx-errors-on-apache-and-nginx\/"},"modified":"2025-12-05T18:23:34","modified_gmt":"2025-12-05T15:23:34","slug":"how-to-read-web-server-logs-to-diagnose-4xx-5xx-errors-on-apache-and-nginx","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/en\/how-to-read-web-server-logs-to-diagnose-4xx-5xx-errors-on-apache-and-nginx\/","title":{"rendered":"How to Read Web Server Logs to Diagnose 4xx\u20135xx Errors on Apache and Nginx"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><p>If you run a website on Apache or Nginx, your access and error logs are the most honest source of truth you have. Every 404, 403, 500 or 502 that users see is already written there line by line. When teams at dchost.com review performance, debug SEO drops or analyze checkout issues, the first place we look is almost always the web server logs. Once you know how to read them, 4xx\u20135xx errors stop being mysterious; they become concrete, traceable events tied to exact URLs, IPs, and timestamps.<\/p>\n<p>In this guide we\u2019ll walk through how to read Apache and Nginx access and error logs with a focus on diagnosing 4xx\u20135xx HTTP errors. We\u2019ll look at real log examples, explain what each field means in plain language, and show practical command\u2011line queries you can copy\u2011paste. Whether you are on shared hosting, a <a href=\"https:\/\/www.dchost.com\/vps\">VPS<\/a>, or a <a href=\"https:\/\/www.dchost.com\/dedicated-server\">dedicated server<\/a> at dchost.com, the workflow is the same: find the right log file, filter for problematic status codes, and connect each error back to configuration or application issues so you can fix them with confidence.<\/p>\n<div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#Why_4xx5xx_Errors_Start_in_Your_Web_Server_Logs\"><span class=\"toc_number toc_depth_1\">1<\/span> Why 4xx\u20135xx Errors Start in Your Web Server Logs<\/a><\/li><li><a href=\"#Quick_Refresher_HTTP_4xx_and_5xx_Status_Codes\"><span class=\"toc_number toc_depth_1\">2<\/span> Quick Refresher: HTTP 4xx and 5xx Status Codes<\/a><ul><li><a href=\"#Common_4xx_Client_Error_Codes\"><span class=\"toc_number toc_depth_2\">2.1<\/span> Common 4xx (Client Error) Codes<\/a><\/li><li><a href=\"#Common_5xx_Server_Error_Codes\"><span class=\"toc_number toc_depth_2\">2.2<\/span> Common 5xx (Server Error) Codes<\/a><\/li><\/ul><\/li><li><a href=\"#Where_to_Find_Apache_and_Nginx_Logs_on_Common_Systems\"><span class=\"toc_number toc_depth_1\">3<\/span> Where to Find Apache and Nginx Logs on Common Systems<\/a><ul><li><a href=\"#Typical_Apache_Log_Locations\"><span class=\"toc_number toc_depth_2\">3.1<\/span> Typical Apache Log Locations<\/a><\/li><li><a href=\"#Typical_Nginx_Log_Locations\"><span class=\"toc_number toc_depth_2\">3.2<\/span> Typical Nginx Log Locations<\/a><\/li><\/ul><\/li><li><a href=\"#Understanding_Access_Log_Formats_With_Real_Examples\"><span class=\"toc_number toc_depth_1\">4<\/span> Understanding Access Log Formats (With Real Examples)<\/a><ul><li><a href=\"#Apache_Combined_Log_Format\"><span class=\"toc_number toc_depth_2\">4.1<\/span> Apache Combined Log Format<\/a><\/li><li><a href=\"#Nginx_Log_Format\"><span class=\"toc_number toc_depth_2\">4.2<\/span> Nginx Log Format<\/a><\/li><\/ul><\/li><li><a href=\"#Understanding_Error_Logs_When_Things_Really_Break\"><span class=\"toc_number toc_depth_1\">5<\/span> Understanding Error Logs: When Things Really Break<\/a><ul><li><a href=\"#Apache_Error_Log_Examples\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Apache Error Log Examples<\/a><\/li><li><a href=\"#Nginx_Error_Log_Examples\"><span class=\"toc_number toc_depth_2\">5.2<\/span> Nginx Error Log Examples<\/a><\/li><\/ul><\/li><li><a href=\"#Step-by-Step_Diagnosing_Common_4xx_Errors_from_Logs\"><span class=\"toc_number toc_depth_1\">6<\/span> Step-by-Step: Diagnosing Common 4xx Errors from Logs<\/a><ul><li><a href=\"#404_Not_Found_Broken_Links_vs_Bot_Noise\"><span class=\"toc_number toc_depth_2\">6.1<\/span> 404 Not Found: Broken Links vs. Bot Noise<\/a><\/li><li><a href=\"#403_Forbidden_Security_Rules_or_Permissions\"><span class=\"toc_number toc_depth_2\">6.2<\/span> 403 Forbidden: Security Rules or Permissions<\/a><\/li><li><a href=\"#401_Unauthorized_Login_Troubles\"><span class=\"toc_number toc_depth_2\">6.3<\/span> 401 Unauthorized: Login Troubles<\/a><\/li><li><a href=\"#429_Too_Many_Requests_Rate_Limiting_in_Action\"><span class=\"toc_number toc_depth_2\">6.4<\/span> 429 Too Many Requests: Rate Limiting in Action<\/a><\/li><\/ul><\/li><li><a href=\"#Step-by-Step_Diagnosing_Common_5xx_Errors_from_Logs\"><span class=\"toc_number toc_depth_1\">7<\/span> Step-by-Step: Diagnosing Common 5xx Errors from Logs<\/a><ul><li><a href=\"#500_Internal_Server_Error_Application_or_Config_Bugs\"><span class=\"toc_number toc_depth_2\">7.1<\/span> 500 Internal Server Error: Application or Config Bugs<\/a><\/li><li><a href=\"#502_Bad_Gateway_and_504_Gateway_Timeout_Upstream_Problems\"><span class=\"toc_number toc_depth_2\">7.2<\/span> 502 Bad Gateway and 504 Gateway Timeout: Upstream Problems<\/a><\/li><li><a href=\"#503_Service_Unavailable_Overload_or_Maintenance\"><span class=\"toc_number toc_depth_2\">7.3<\/span> 503 Service Unavailable: Overload or Maintenance<\/a><\/li><\/ul><\/li><li><a href=\"#Practical_Log_Analysis_Commands_Youll_Actually_Use\"><span class=\"toc_number toc_depth_1\">8<\/span> Practical Log Analysis Commands You\u2019ll Actually Use<\/a><ul><li><a href=\"#Follow_Logs_in_Real_Time\"><span class=\"toc_number toc_depth_2\">8.1<\/span> Follow Logs in Real Time<\/a><\/li><li><a href=\"#Filter_by_Status_Code_Range_4xx5xx\"><span class=\"toc_number toc_depth_2\">8.2<\/span> Filter by Status Code Range (4xx\/5xx)<\/a><\/li><li><a href=\"#Find_Slow_Requests_that_Also_Error\"><span class=\"toc_number toc_depth_2\">8.3<\/span> Find Slow Requests that Also Error<\/a><\/li><li><a href=\"#Find_Error_Spikes_by_Minute\"><span class=\"toc_number toc_depth_2\">8.4<\/span> Find Error Spikes by Minute<\/a><\/li><\/ul><\/li><li><a href=\"#Turn_Logs_into_Monitoring_Alerts_and_When_to_Upgrade_Hosting\"><span class=\"toc_number toc_depth_1\">9<\/span> Turn Logs into Monitoring &amp; Alerts (and When to Upgrade Hosting)<\/a><ul><li><a href=\"#Centralised_Logging_on_a_VPS\"><span class=\"toc_number toc_depth_2\">9.1<\/span> Centralised Logging on a VPS<\/a><\/li><li><a href=\"#Meaningful_Alert_Rules_Based_on_4xx5xx\"><span class=\"toc_number toc_depth_2\">9.2<\/span> Meaningful Alert Rules Based on 4xx\u20135xx<\/a><\/li><li><a href=\"#When_Logs_Tell_You_Its_Time_to_Scale\"><span class=\"toc_number toc_depth_2\">9.3<\/span> When Logs Tell You It\u2019s Time to Scale<\/a><\/li><\/ul><\/li><li><a href=\"#Hardening_Performance_and_Next_Steps\"><span class=\"toc_number toc_depth_1\">10<\/span> Hardening, Performance, and Next Steps<\/a><\/li><\/ul><\/div>\n<h2><span id=\"Why_4xx5xx_Errors_Start_in_Your_Web_Server_Logs\">Why 4xx\u20135xx Errors Start in Your Web Server Logs<\/span><\/h2>\n<p>HTTP status codes are your web server\u2019s way of describing what happened to each request. 2xx means success, 3xx means redirect, 4xx means a client\u2011side problem, and 5xx means a server\u2011side failure. Browser error pages are only a tiny, user\u2011facing summary. The details live in your logs.<\/p>\n<p>When we review incidents for our customers, almost every meaningful question can be answered from logs:<\/p>\n<ul>\n<li><strong>\u201cAre these 404s caused by bots, broken internal links, or old external links?\u201d<\/strong> \u2192 Check referrer and user agent in access logs.<\/li>\n<li><strong>\u201cWhy are we getting random 500 errors on checkout?\u201d<\/strong> \u2192 Correlate 500s in access logs with PHP or application errors in error logs.<\/li>\n<li><strong>\u201cIs that 503 throttle from the app or from the web server?\u201d<\/strong> \u2192 Compare app logs, web server error logs, and upstream timeouts.<\/li>\n<\/ul>\n<p>We already covered what the main HTTP codes mean for SEO and redirects in our article <a href=\"https:\/\/www.dchost.com\/blog\/en\/http-durum-kodlari-seo-ve-hosting-icin-301-302-404-410-ve-5xx-rehberi\/\">What HTTP Status Codes Mean for SEO and Hosting<\/a>. In this article we\u2019ll stay at the server layer and focus on how to read the raw log lines that generate those codes, especially 4xx and 5xx, so you can move from guessing to precise diagnosis.<\/p>\n<h2><span id=\"Quick_Refresher_HTTP_4xx_and_5xx_Status_Codes\">Quick Refresher: HTTP 4xx and 5xx Status Codes<\/span><\/h2>\n<p>Before diving into logs, it helps to have a mental map of the most common 4xx\u20135xx codes you\u2019ll see.<\/p>\n<h3><span id=\"Common_4xx_Client_Error_Codes\">Common 4xx (Client Error) Codes<\/span><\/h3>\n<ul>\n<li><strong>400 Bad Request<\/strong> \u2013 The request is malformed (invalid headers, too long URL, or broken syntax). Often logged with extra info in error logs.<\/li>\n<li><strong>401 Unauthorized<\/strong> \u2013 Authentication required or failed. Usually combined with <code>WWW-Authenticate<\/code> headers.<\/li>\n<li><strong>403 Forbidden<\/strong> \u2013 The server understood the request but refuses to authorize it. Common with directory restrictions or security rules.<\/li>\n<li><strong>404 Not Found<\/strong> \u2013 Requested URL doesn\u2019t exist or rewrite rules mis\u2011route it.<\/li>\n<li><strong>405 Method Not Allowed<\/strong> \u2013 Method (POST, PUT, DELETE) is not allowed for this endpoint.<\/li>\n<li><strong>408 Request Timeout<\/strong> \u2013 Client took too long to send the full request.<\/li>\n<li><strong>429 Too Many Requests<\/strong> \u2013 Rate limiting by web server, WAF or application.<\/li>\n<\/ul>\n<h3><span id=\"Common_5xx_Server_Error_Codes\">Common 5xx (Server Error) Codes<\/span><\/h3>\n<ul>\n<li><strong>500 Internal Server Error<\/strong> \u2013 Generic error; often PHP, application or configuration failure.<\/li>\n<li><strong>502 Bad Gateway<\/strong> \u2013 Web server (reverse proxy) couldn\u2019t get a valid response from upstream (PHP\u2011FPM, Node.js, etc.).<\/li>\n<li><strong>503 Service Unavailable<\/strong> \u2013 Server is overloaded, under maintenance, or backend pool is down.<\/li>\n<li><strong>504 Gateway Timeout<\/strong> \u2013 Upstream took too long to respond; often a slow database or external API.<\/li>\n<\/ul>\n<p>Your Apache or Nginx access log records every one of these responses. The error log will often explain <em>why<\/em> the server picked that code. Reading both together is the key skill you want to build.<\/p>\n<h2><span id=\"Where_to_Find_Apache_and_Nginx_Logs_on_Common_Systems\">Where to Find Apache and Nginx Logs on Common Systems<\/span><\/h2>\n<p>Exact paths depend on your OS and control panel, but most dchost.com VPS and dedicated servers follow standard Linux conventions.<\/p>\n<h3><span id=\"Typical_Apache_Log_Locations\">Typical Apache Log Locations<\/span><\/h3>\n<ul>\n<li><strong>Debian\/Ubuntu<\/strong><br \/>\n    <code>\/var\/log\/apache2\/access.log<\/code><br \/>\n    <code>\/var\/log\/apache2\/error.log<\/code><\/li>\n<li><strong>CentOS \/ AlmaLinux \/ Rocky Linux<\/strong><br \/>\n    <code>\/var\/log\/httpd\/access_log<\/code><br \/>\n    <code>\/var\/log\/httpd\/error_log<\/code><\/li>\n<li><strong>Per\u2011vHost logs (common on panels)<\/strong><br \/>\n    Something like <code>\/home\/USER\/logs\/domain.com-access_log<\/code> and <code>domain.com-error_log<\/code><\/li>\n<\/ul>\n<h3><span id=\"Typical_Nginx_Log_Locations\">Typical Nginx Log Locations<\/span><\/h3>\n<ul>\n<li><strong>All major Linux distros<\/strong><br \/>\n    <code>\/var\/log\/nginx\/access.log<\/code><br \/>\n    <code>\/var\/log\/nginx\/error.log<\/code><\/li>\n<li><strong>Per\u2011site logs<\/strong> (based on your vhost config)<br \/>\n    Example snippet:<br \/>\n    <code>access_log \/var\/log\/nginx\/example.com.access.log main;<\/code><br \/>\n    <code>error_log  \/var\/log\/nginx\/example.com.error.log warn;<\/code><\/li>\n<\/ul>\n<p>On shared hosting, you may only see per\u2011domain logs inside your home directory; on a VPS or dedicated server you have full root\u2011level access to all logs. If you\u2019re planning a move from shared hosting to a VPS primarily for better observability and control, our checklist <a href=\"https:\/\/www.dchost.com\/blog\/en\/paylasimli-hostingden-vpse-nasil-gecersin-kesintisiz-tasima-icin-sicacik-bir-kontrol-listesi\/\">for moving from shared hosting to a VPS with zero downtime<\/a> is a good companion read.<\/p>\n<h2><span id=\"Understanding_Access_Log_Formats_With_Real_Examples\">Understanding Access Log Formats (With Real Examples)<\/span><\/h2>\n<p>Access logs are usually in either <strong>Common Log Format (CLF)<\/strong> or <strong>Combined Log Format<\/strong>. Combined is more useful for 4xx\u20135xx diagnosis because it includes referrer and user agent.<\/p>\n<h3><span id=\"Apache_Combined_Log_Format\">Apache Combined Log Format<\/span><\/h3>\n<p>Definition (from <code>LogFormat<\/code>):<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">%h %l %u %t &quot;%r&quot; %&gt;s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot;<\/code><\/pre>\n<p>Example line:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">203.0.113.45 - - [05\/Dec\/2025:10:23:12 +0000] &quot;GET \/checkout HTTP\/1.1&quot; 500 512 &quot;https:\/\/example.com\/cart&quot; &quot;Mozilla\/5.0 ...&quot;<\/code><\/pre>\n<p>Reading it from left to right:<\/p>\n<ul>\n<li><strong>203.0.113.45<\/strong> \u2013 Client IP<\/li>\n<li><strong>&#8211; &#8211;<\/strong> \u2013 Unused identifiers (typically <code>identd<\/code> and authenticated user)<\/li>\n<li><strong>[05\/Dec\/2025:10:23:12 +0000]<\/strong> \u2013 Timestamp<\/li>\n<li><strong>&#8220;GET \/checkout HTTP\/1.1&#8221;<\/strong> \u2013 Request line: method, URL, protocol<\/li>\n<li><strong>500<\/strong> \u2013 Status code (here, a server error)<\/li>\n<li><strong>512<\/strong> \u2013 Response size in bytes<\/li>\n<li><strong>&#8220;https:\/\/example.com\/cart&#8221;<\/strong> \u2013 Referrer (where the user came from)<\/li>\n<li><strong>&#8220;Mozilla\/5.0 &#8230;&#8221;<\/strong> \u2013 User agent (browser, bot, app)<\/li>\n<\/ul>\n<p>Just from this one line you already know: a real browser (probably) clicked \u201cProceed to checkout\u201d from the cart page and got a 500. That\u2019s enough to start reproducing and then check error logs or application logs.<\/p>\n<h3><span id=\"Nginx_Log_Format\">Nginx Log Format<\/span><\/h3>\n<p>Nginx lets you define <code>log_format<\/code>. A common \u201ccombined\u201d style format looks like:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">log_format main '$remote_addr - $remote_user [$time_local] &quot;$request&quot; '\n                '$status $body_bytes_sent &quot;$http_referer&quot; '\n                '&quot;$http_user_agent&quot; &quot;$request_time&quot;';<\/code><\/pre>\n<p>Example line:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">203.0.113.45 - - [05\/Dec\/2025:10:23:12 +0000] &quot;POST \/api\/login HTTP\/2.0&quot; 401 178 &quot;https:\/\/app.example.com\/&quot; &quot;Mozilla\/5.0 ...&quot; &quot;0.123&quot;<\/code><\/pre>\n<ul>\n<li><strong>401<\/strong> \u2013 Authentication failed<\/li>\n<li><strong>&#8220;0.123&#8221;<\/strong> \u2013 Request processing time in seconds (very handy when debugging slow 5xx responses)<\/li>\n<\/ul>\n<p>The key for 4xx\u20135xx diagnosis is simple: <strong>spot the non\u20112xx codes, then read the surrounding fields like a story.<\/strong> Who requested what, from which page, with which user agent, and how long it took.<\/p>\n<h2><span id=\"Understanding_Error_Logs_When_Things_Really_Break\">Understanding Error Logs: When Things Really Break<\/span><\/h2>\n<p>Access logs tell you <em>that<\/em> a request returned 500. Error logs tell you <em>why<\/em>. Let\u2019s look at a few common patterns.<\/p>\n<h3><span id=\"Apache_Error_Log_Examples\">Apache Error Log Examples<\/span><\/h3>\n<p>Example: PHP fatal error causing a 500:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">[Fri Dec 05 10:23:12.345678 2025] [proxy_fcgi:error] [pid 12345:tid 140123456789] [client 203.0.113.45:51724] AH01071: Got error 'PHP Fatal error:  Uncaught Error: Call to undefined function wc_get_cart() in \/home\/user\/public_html\/wp-content\/plugins\/custom-checkout.php:42n'<\/code><\/pre>\n<p>Pieces to notice:<\/p>\n<ul>\n<li><strong>[proxy_fcgi:error]<\/strong> \u2013 The module that logged the error (here, PHP\u2011FPM proxy).<\/li>\n<li><strong>[client 203.0.113.45:51724]<\/strong> \u2013 Same IP you\u2019ll see in access log.<\/li>\n<li><strong>PHP Fatal error&#8230;<\/strong> \u2013 The actual application\u2011level cause.<\/li>\n<\/ul>\n<p>Now you can correlate this exact timestamp and client IP with the matching line in <code>access.log<\/code> to see the URL and referrer.<\/p>\n<p>Example: ModSecurity or access rules causing a 403:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">[Fri Dec 05 10:31:00.123456 2025] [authz_core:error] [pid 22345:tid 140223456789] [client 198.51.100.77:38210] AH01630: client denied by server configuration: \/home\/user\/public_html\/wp-admin\/admin-ajax.php<\/code><\/pre>\n<p>This tells you the 403 is from Apache\u2019s authorization layer, not from WordPress itself. That matters a lot when tuning WAF rules or .htaccess protection.<\/p>\n<h3><span id=\"Nginx_Error_Log_Examples\">Nginx Error Log Examples<\/span><\/h3>\n<p>Example: PHP\u2011FPM timeout causing a 504:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">2025\/12\/05 10:45:22 [error] 1234#1234: *56789 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 203.0.113.45, server: example.com, request: &quot;GET \/report?month=12 HTTP\/2.0&quot;, upstream: &quot;fastcgi:\/\/unix:\/var\/run\/php-fpm.sock&quot;, host: &quot;example.com&quot;<\/code><\/pre>\n<p>Important bits:<\/p>\n<ul>\n<li><strong>upstream timed out<\/strong> \u2013 Nginx didn\u2019t get a response in time.<\/li>\n<li><strong>request: &#8220;GET \/report?month=12&#8221;<\/strong> \u2013 Exact URL causing timeouts.<\/li>\n<li><strong>upstream: &#8220;fastcgi:\/\/unix:\/var\/run\/php-fpm.sock&#8221;<\/strong> \u2013 The backend that is slow (likely CPU\/DB issues).<\/li>\n<\/ul>\n<p>Example: 404 caused by missing file or bad rewrite:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">2025\/12\/05 11:10:00 [error] 1234#1234: *57000 open() &quot;\/home\/user\/public_html\/wp-content\/themes\/theme\/assets\/js\/app.js&quot; failed (2: No such file or directory), client: 198.51.100.10, server: example.com, request: &quot;GET \/wp-content\/themes\/theme\/assets\/js\/app.js HTTP\/2.0&quot;, host: &quot;example.com&quot;<\/code><\/pre>\n<p>Here you know instantly: the file truly does not exist at that path. This is very different from a 404 caused by application routing, which might not generate an error log entry at all.<\/p>\n<h2><span id=\"Step-by-Step_Diagnosing_Common_4xx_Errors_from_Logs\">Step-by-Step: Diagnosing Common 4xx Errors from Logs<\/span><\/h2>\n<p>Let\u2019s walk through concrete workflows for the 4xx errors you\u2019ll see most often.<\/p>\n<h3><span id=\"404_Not_Found_Broken_Links_vs_Bot_Noise\">404 Not Found: Broken Links vs. Bot Noise<\/span><\/h3>\n<p>First, see how many 404s you have and which URLs are affected.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># Apache\nawk '$9 ~ \/^404$\/' \/var\/log\/apache2\/access.log | head\n\n# Nginx (status is field 9 in typical formats)\nawk '{ if ($9 == 404) print }' \/var\/log\/nginx\/access.log | head<\/code><\/pre>\n<p>Now, group by URL to find the worst offenders:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">awk '$9 == 404 {print $7}' \/var\/log\/nginx\/access.log | sort | uniq -c | sort -nr | head<\/code><\/pre>\n<p>This shows counts and paths: maybe <code>\/old-blog-post<\/code>, <code>\/wp-login.php<\/code>, or random bot paths like <code>\/.env<\/code>.<\/p>\n<ul>\n<li><strong>If you see many 404s on real pages<\/strong> that used to exist, add redirects (301\/410). Our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/http-durum-kodlari-seo-ve-hosting-icin-301-302-404-410-ve-5xx-rehberi\/\">HTTP status codes, SEO and hosting<\/a> explains when 301 vs 410 is the right choice.<\/li>\n<li><strong>If 404s are bot scans<\/strong> for <code>\/wp-admin<\/code>, <code>\/.git<\/code>, <code>\/phpmyadmin<\/code> etc., that\u2019s normal background noise, but you may want to harden security or add WAF rules.<\/li>\n<\/ul>\n<p>You can also break down 404s by referrer:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">awk '$9 == 404 {print $11}' \/var\/log\/apache2\/access.log | sed 's\/&quot;\/\/g' | sort | uniq -c | sort -nr | head<\/code><\/pre>\n<p>This tells you whether 404s are coming from your own pages (internal links to fix) or from external sites.<\/p>\n<h3><span id=\"403_Forbidden_Security_Rules_or_Permissions\">403 Forbidden: Security Rules or Permissions<\/span><\/h3>\n<p>For 403s you always want to check both access and error logs.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">awk '$9 == 403 {print $1, $4, $5, $7}' \/var\/log\/nginx\/access.log | head<\/code><\/pre>\n<p>Then inspect matching error log entries around the same timestamp:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">grep &quot;[client 198.51.100.77&quot; \/var\/log\/apache2\/error.log | tail<\/code><\/pre>\n<p>Common 403 causes:<\/p>\n<ul>\n<li><strong>Directory or file permissions<\/strong> (e.g. <code>chmod 600<\/code> on static assets).<\/li>\n<li><strong>.htaccess or Nginx rules<\/strong> that deny certain IPs, paths or user agents.<\/li>\n<li><strong>ModSecurity \/ WAF rules<\/strong> blocking suspicious patterns in query strings.<\/li>\n<\/ul>\n<p>If your 403s are mostly WAF\u2011related, our deep dive on <a href=\"https:\/\/www.dchost.com\/blog\/en\/modsecurity-ve-owasp-crs-ile-wafi-uysallastirmak-yanlis-pozitifleri-nasil-ehlilestirir-performansi-ne-zaman-ucururuz\/\">tuning ModSecurity and OWASP CRS to cut false positives<\/a> will help you reduce noise without weakening security.<\/p>\n<h3><span id=\"401_Unauthorized_Login_Troubles\">401 Unauthorized: Login Troubles<\/span><\/h3>\n<p>For 401 errors, look at:<\/p>\n<ul>\n<li><strong>Path<\/strong> \u2013 Is it an API endpoint, admin panel, or HTTP Basic Auth area?<\/li>\n<li><strong>User agent<\/strong> \u2013 Real browsers vs. scripts vs. integrations.<\/li>\n<li><strong>Rate<\/strong> \u2013 Is someone brute\u2011forcing passwords?<\/li>\n<\/ul>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">awk '$9 == 401 {print $1, $7, $11}' \/var\/log\/apache2\/access.log | sort | head<\/code><\/pre>\n<p>If you see many 401s from the same IP, combine logs with your authentication system\u2019s logs and consider temporary IP blocking (fail2ban, Nginx limit rules, etc.).<\/p>\n<h3><span id=\"429_Too_Many_Requests_Rate_Limiting_in_Action\">429 Too Many Requests: Rate Limiting in Action<\/span><\/h3>\n<p>429s are usually great news: your rate limiting is working. But they can also hurt real users if thresholds are wrong.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">awk '$9 == 429 {print $1, $7}' \/var\/log\/nginx\/access.log | sort | uniq -c | sort -nr | head<\/code><\/pre>\n<p>Ask yourself:<\/p>\n<ul>\n<li>Are 429s mostly from one or a handful of IPs? \u2192 Likely bots or scraping tools.<\/li>\n<li>Are real users hitting 429 on checkout or cart APIs? \u2192 Limits may be too strict.<\/li>\n<\/ul>\n<p>Our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/e-ticaret-sepet-ve-odeme-adimlarini-izlemek-sunucu-loglari-ve-alarm-kurallari\/\">monitoring cart and checkout steps with server logs and alerts<\/a> shows how we use 4xx\/5xx patterns to spot real customer friction in e\u2011commerce flows.<\/p>\n<h2><span id=\"Step-by-Step_Diagnosing_Common_5xx_Errors_from_Logs\">Step-by-Step: Diagnosing Common 5xx Errors from Logs<\/span><\/h2>\n<p>5xx errors are usually more urgent because they mean your server or app failed. Here\u2019s how to quickly narrow down causes.<\/p>\n<h3><span id=\"500_Internal_Server_Error_Application_or_Config_Bugs\">500 Internal Server Error: Application or Config Bugs<\/span><\/h3>\n<p>Start by listing recent 500s:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">awk '$9 == 500 {print $4, $5, $7}' \/var\/log\/apache2\/access.log | tail -n 50<\/code><\/pre>\n<p>Then jump to the error log around those times:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">tail -n 200 \/var\/log\/apache2\/error.log<\/code><\/pre>\n<p>Typical patterns:<\/p>\n<ul>\n<li><strong>PHP Fatal error \/ Uncaught exception<\/strong> \u2013 Bug or missing dependency.<\/li>\n<li><strong>Rewrite rules loop<\/strong> \u2013 Misconfigured <code>.htaccess<\/code> or <code>try_files<\/code>.<\/li>\n<li><strong>Permissions problems<\/strong> \u2013 App can\u2019t write to cache or storage directories.<\/li>\n<\/ul>\n<p>If 500s cluster around heavy operations (checkout, reporting, imports), combine this with application and database logs. For PHP apps like WordPress or WooCommerce, our guides on <a href=\"https:\/\/www.dchost.com\/blog\/en\/wordpress-beyaz-ekran-hatasi-cozumu-hosting-ve-php-tarafli-adim-adim-rehber\/\">fixing WordPress white screen of death from the hosting side<\/a> and <a href=\"https:\/\/www.dchost.com\/blog\/en\/woocommerce-icin-mysql-innodb-tuning-kontrol-listesi-buffer-pool-indeksleme-ve-slow-query-analizi-nasil-akillica-yapilir\/\">MySQL\/InnoDB tuning for WooCommerce<\/a> show how server\u2011side tuning reduces 5xx incidents dramatically.<\/p>\n<h3><span id=\"502_Bad_Gateway_and_504_Gateway_Timeout_Upstream_Problems\">502 Bad Gateway and 504 Gateway Timeout: Upstream Problems<\/span><\/h3>\n<p>502\/504 almost always mean your reverse proxy (Apache mod_proxy, Nginx, or a load balancer) couldn\u2019t talk to the application backend properly.<\/p>\n<p>In access logs they just show up as status 502\/504. The real story is in error logs:<\/p>\n<ul>\n<li><strong>Apache + PHP\u2011FPM<\/strong><br \/>\n    Look for <code>AH01071: Got error 'Primary script unknown'<\/code> (wrong <code>DOCUMENT_ROOT<\/code> or script path) or socket connection errors.<\/li>\n<li><strong>Nginx + PHP\u2011FPM<\/strong><br \/>\n    Look for <code>upstream timed out<\/code> or <code>connect() to unix:\/var\/run\/php-fpm.sock failed<\/code>.<\/li>\n<\/ul>\n<p>Checklist when you see many 502\/504:<\/p>\n<ul>\n<li>Is the upstream process running? (<code>php-fpm<\/code>, <code>node<\/code>, <code>gunicorn<\/code>, etc.)<\/li>\n<li>Is the socket\/port correct between web server and app?<\/li>\n<li>Are timeouts too low for heavy background tasks?<\/li>\n<li>Is CPU\/IO saturated? (Check <code>top<\/code>, <code>htop<\/code>, <code>iostat<\/code>.)<\/li>\n<\/ul>\n<p>If resource exhaustion is frequent, it may be time to scale resources or separate app and database servers. Our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/9-server-side-signals-its-time-to-upgrade-your-hosting-plan\/\">9 server\u2011side signals it\u2019s time to upgrade your hosting plan<\/a> explains which log\u2011level symptoms mean \u201ctuning is not enough anymore.\u201d<\/p>\n<h3><span id=\"503_Service_Unavailable_Overload_or_Maintenance\">503 Service Unavailable: Overload or Maintenance<\/span><\/h3>\n<p>503 can come from either the web server or the application. Look for hints:<\/p>\n<ul>\n<li><strong>Nginx<\/strong> \u2013 <code>no live upstreams while connecting to upstream<\/code> indicates all backend servers are down or marked failed.<\/li>\n<li><strong>Application<\/strong> \u2013 Custom HTML saying \u201cWe\u2019re under maintenance\u201d while access logs show 503 but error logs are quiet.<\/li>\n<\/ul>\n<p>Key questions:<\/p>\n<ul>\n<li>Do 503s correlate with traffic peaks? \u2192 CPU\/RAM or database contention.<\/li>\n<li>Do 503s appear after deploys? \u2192 App maintenance mode toggled incorrectly.<\/li>\n<\/ul>\n<p>Reading logs around traffic spikes alongside system metrics is where proper monitoring pays off. We have a dedicated guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-izleme-ve-alarm-kurulumu-prometheus-grafana-ve-uptime-kuma-ile-baslangic\/\">VPS monitoring and alerts with Prometheus, Grafana and Uptime Kuma<\/a> that fits neatly on top of the log techniques in this article.<\/p>\n<h2><span id=\"Practical_Log_Analysis_Commands_Youll_Actually_Use\">Practical Log Analysis Commands You\u2019ll Actually Use<\/span><\/h2>\n<p>You don\u2019t need a full SIEM stack to start getting value from logs. A handful of shell commands will take you very far on any dchost.com VPS or dedicated server.<\/p>\n<h3><span id=\"Follow_Logs_in_Real_Time\">Follow Logs in Real Time<\/span><\/h3>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># Access logs\nsudo tail -f \/var\/log\/nginx\/access.log\n\n# Error logs\nsudo tail -f \/var\/log\/nginx\/error.log<\/code><\/pre>\n<p>Trigger the error in your browser and watch the line appear in real time. This is the simplest and most underrated technique.<\/p>\n<h3><span id=\"Filter_by_Status_Code_Range_4xx5xx\">Filter by Status Code Range (4xx\/5xx)<\/span><\/h3>\n<p>With <code>awk<\/code> you can quickly filter 4xx and 5xx:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># All 4xx\nawk '$9 ~ \/^4[0-9][0-9]$\/' \/var\/log\/apache2\/access.log | head\n\n# All 5xx\nawk '$9 ~ \/^5[0-9][0-9]$\/' \/var\/log\/nginx\/access.log | head<\/code><\/pre>\n<p>To see top IPs causing 5xx:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">awk '$9 ~ \/^5[0-9][0-9]$\/ {print $1}' \/var\/log\/nginx\/access.log | \n  sort | uniq -c | sort -nr | head<\/code><\/pre>\n<h3><span id=\"Find_Slow_Requests_that_Also_Error\">Find Slow Requests that Also Error<\/span><\/h3>\n<p>If your Nginx log format includes <code>$request_time<\/code> as last field:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># Slow 5xx (request_time &gt; 2 seconds)\nawk '$9 ~ \/^5\/ &amp;&amp; $NF &gt; 2 {print $4, $5, $7, $9, $NF}' \/var\/log\/nginx\/access.log | head<\/code><\/pre>\n<p>This shows which endpoints both fail and are slow, helping you focus optimization on high\u2011impact areas.<\/p>\n<h3><span id=\"Find_Error_Spikes_by_Minute\">Find Error Spikes by Minute<\/span><\/h3>\n<p>To see if errors come in bursts:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">awk '$9 ~ \/^5\/ {gsub(&quot;[:[]&quot;,&quot; &quot;,$4); print $4&quot; &quot;$5}' \/var\/log\/apache2\/access.log | \n  awk '{print $1&quot; &quot;$2&quot;:&quot;$3}' | sort | uniq -c | sort -nr | head<\/code><\/pre>\n<p>This aggregates 5xx counts by minute, so you can correlate with deploy times, cron jobs, or traffic surges.<\/p>\n<h2><span id=\"Turn_Logs_into_Monitoring_Alerts_and_When_to_Upgrade_Hosting\">Turn Logs into Monitoring &amp; Alerts (and When to Upgrade Hosting)<\/span><\/h2>\n<p>Reading logs manually is great during debugging, but long\u2011term reliability comes from automation: centralizing logs, setting retention, and creating alert rules based on 4xx\u20135xx patterns.<\/p>\n<h3><span id=\"Centralised_Logging_on_a_VPS\">Centralised Logging on a VPS<\/span><\/h3>\n<p>On multi\u2011server architectures (e.g. separate web, app and database servers) we strongly recommend central logging. Instead of SSH\u2011ing into 3\u20134 machines and grepping logs, you send everything to a single place for querying and dashboards.<\/p>\n<p>We\u2019ve shared a full playbook in <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-log-yonetimi-nasil-rayina-oturur-grafana-loki-promtail-ile-merkezi-loglama-tutma-sureleri-ve-alarm-kurallari\/\">VPS log management without the drama: centralised logging with Grafana Loki + Promtail<\/a>. The same principles apply whether you run one dchost.com VPS or a fleet of dedicated servers and colocation machines.<\/p>\n<h3><span id=\"Meaningful_Alert_Rules_Based_on_4xx5xx\">Meaningful Alert Rules Based on 4xx\u20135xx<\/span><\/h3>\n<p>Instead of \u201calert on any 500\u201d, it\u2019s more practical to define:<\/p>\n<ul>\n<li><strong>Error rate thresholds<\/strong> \u2013 e.g. \u201c5xx &gt; 1% of requests for 5 minutes\u201d.<\/li>\n<li><strong>Path\u2011specific alerts<\/strong> \u2013 e.g. \u201cAny 500\/502 on \/checkout or \/payment callbacks\u201d.<\/li>\n<li><strong>Spike detection<\/strong> \u2013 \u201c404s on a single URL &gt; 100\/minute\u201d (often broken campaign links or bot waves).<\/li>\n<\/ul>\n<p>In practice we combine these with business\u2011level events (orders per minute, signup success rate) so that not every 500 wakes you up, but problems that actually hurt users always get attention.<\/p>\n<h3><span id=\"When_Logs_Tell_You_Its_Time_to_Scale\">When Logs Tell You It\u2019s Time to Scale<\/span><\/h3>\n<p>Sometimes logs make it clear that the problem isn\u2019t a bug, but capacity. Signs include:<\/p>\n<ul>\n<li>Regular 502\/504 timeouts at predictable traffic levels.<\/li>\n<li>503s coinciding with CPU at 90\u2013100% and DB load spikes.<\/li>\n<li>429 or rate\u2011limit patterns where you are forced to be overly strict to keep servers alive.<\/li>\n<\/ul>\n<p>In those cases, optimizing queries and caching is still important, but it\u2019s also time to review your hosting resources (CPU, RAM, NVMe, bandwidth). Our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/woocommerce-kapasite-planlama-rehberi-vcpu-ram-iops-nasil-hesaplanir\/\">capacity planning for WooCommerce in terms of vCPU, RAM and IOPS<\/a> gives a concrete way to link what you see in logs with what you should provision on your next dchost.com VPS or dedicated server.<\/p>\n<h2><span id=\"Hardening_Performance_and_Next_Steps\">Hardening, Performance, and Next Steps<\/span><\/h2>\n<p>Web server logs are not just for \u201csomething is broken\u201d moments. Once you\u2019re comfortable reading 4xx\u20135xx patterns, you can also use logs to harden security, tune caching, and plan upgrades calmly.<\/p>\n<ul>\n<li><strong>Security hardening<\/strong> \u2013 403\/401\/404 patterns reveal brute\u2011force attempts, path discovery scans and vulnerable plugins. Combine this with a solid baseline from our <a href=\"https:\/\/www.dchost.com\/blog\/en\/yeni-acilan-web-siteleri-icin-hosting-guvenlik-check-listi-ilk-gunden-yapilmasi-gereken-20-ayar\/\">security checklist for new websites<\/a> to close obvious doors.<\/li>\n<li><strong>Performance tuning<\/strong> \u2013 High 5xx rates on specific endpoints often point at slow database queries, missing indexes or lack of caching. Use logs to prioritize which pages to optimize first.<\/li>\n<li><strong>SEO &amp; UX<\/strong> \u2013 Persistent 404s on important URLs hurt both search visibility and user trust. Logs help you spot and fix those faster than waiting for search console reports.<\/li>\n<\/ul>\n<p>At dchost.com our domain, hosting, VPS, dedicated server and colocation customers all benefit from one simple idea: <strong>logs first<\/strong>. Before throwing more hardware at a problem or rewriting half the application, we always start by reading what Apache or Nginx are already telling us about 4xx\u20135xx errors. Most issues become obvious once you see the exact combination of IP, URL, status, response time and backend error.<\/p>\n<p>If you\u2019re currently on a setup where you don\u2019t have full log access, or you\u2019re fighting recurring 500\/502\/503 errors without clear visibility, this is a good time to rethink your infrastructure. A right\u2011sized VPS or dedicated server at dchost.com, with proper log retention and monitoring, gives you the control you need to debug calmly instead of guessing. And if you\u2019re unsure where to start, our team is happy to help you design a stack where Apache or Nginx logs, application logs and metrics all line up\u2014so the next 4xx\u20135xx incident is just another small, well\u2011understood story in your logs, not a crisis.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>If you run a website on Apache or Nginx, your access and error logs are the most honest source of truth you have. Every 404, 403, 500 or 502 that users see is already written there line by line. When teams at dchost.com review performance, debug SEO drops or analyze checkout issues, the first place [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2957,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-2956","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/2956","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/comments?post=2956"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/2956\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media\/2957"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media?parent=2956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/categories?post=2956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/tags?post=2956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}