$linuxjunkies
>

Squid Debug Logging: Turn It On and Read It

Learn how to enable Squid debug_options, navigate cache.log and access.log, and trace the exact cause of a denied or failed proxy request.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • Squid 5 or 6 installed and running as a systemd service
  • Root or sudo access to edit /etc/squid/squid.conf and read log files
  • A reproducible failing request to test against
  • Sufficient free disk space (at least 2 GB) before raising debug levels

Squid's default logging tells you what happened; debug logging tells you why. When a client gets an unexpected TCP_DENIED, a cache miss makes no sense, or an SSL bump handshake silently fails, the answer is almost always buried in cache.log at a higher verbosity level. This guide walks through enabling debug sections, reading the output without going blind, and tracing a failed request from symptom to root cause.

How Squid Debug Logging Works

Squid organises its source code into numbered sections, each covering a subsystem (ACLs, DNS, SSL, disk cache, and so on). The debug_options directive in squid.conf controls which sections log and at what verbosity level (1–9, where 9 is maximally verbose). The syntax is:

debug_options section,level [section,level ...]

The special token ALL applies a level to every section. ALL,1 is the compiled-in default — only critical events. ALL,9 floods the disk; use it only briefly and on a low-traffic proxy.

Key Debug Sections

SectionSubsystemWhen to raise it
5Disk I/O / storeCache read/write failures
11HTTP client sideMalformed requests, keep-alive issues
14URL parser / hostnameOdd domain handling
20ACL matchingUnexpected DENY or ALLOW results
28Access control (http_access)Policy evaluation trace
33DNS / FQDN lookupsSlow or failing name resolution
44Peer selection / hierarchyCache peer routing failures
83SSL / TLS (bump)Certificate errors, handshake failures

A complete list ships with every Squid release; look for src/debug.cc or run squid -v to find the build path, then consult the official Squid debug sections wiki page.

Step 1 — Edit squid.conf

Open the main configuration file. The default path varies slightly:

  • Debian/Ubuntu: /etc/squid/squid.conf
  • Fedora/RHEL/Rocky: /etc/squid/squid.conf
  • Arch: /etc/squid/squid.conf

Find any existing debug_options line (or add one near the top of the file). To debug ACL denials and SSL issues simultaneously without nuking the whole log:

debug_options ALL,1 20,5 28,5 83,5

This keeps everything else at level 1 while raising ACL matching, access control, and SSL to level 5. For a complete trace of a single subsystem during a controlled test, go to level 9:

debug_options ALL,1 20,9 28,9

Never leave level 9 active in production. A busy proxy can write gigabytes per minute to cache.log and saturate the disk.

Step 2 — Restart or Reload Squid

A full restart is the safest way to activate a new debug_options line because some settings are not re-read on a reload:

sudo systemctl restart squid

On RHEL/Rocky the service may be named squid or, on older installs, require the explicit unit:

sudo systemctl restart squid.service

Confirm Squid came back up:

systemctl status squid

Step 3 — Reproduce the Problem and Capture the Log

Tail cache.log in one terminal while triggering the failing request from the client in another. The log path is set by cache_log in squid.conf; the default is:

sudo tail -f /var/log/squid/cache.log

On Arch, Squid may write to /var/log/squid4/cache.log depending on the AUR package build.

To save a timestamped snapshot for later analysis rather than reading live:

sudo tail -n 5000 /var/log/squid/cache.log > /tmp/squid-debug-$(date +%Y%m%d-%H%M%S).log

Step 4 — Understand the cache.log Format

Each debug line follows this pattern:

YYYY/MM/DD HH:MM:SS.mmm kid1| section,level: message

A real (shortened) example from an ACL denial at level 5:

2024/05/10 14:32:01.847 kid1| 28,5: ACLChecklist::matchAndFinish: aclname=blocked_domains result=1 (implicit DENY)
2024/05/10 14:32:01.848 kid1| 20,5: ACL::matches: 'blocked_domains' for example.evil: MATCH

The kid1 token is Squid's SMP worker identifier. On a single-worker setup you will only see kid1; SMP deployments add kid2, kid3, and so on. Filter to a single worker with grep when needed.

Step 5 — Read access.log Alongside cache.log

The access.log records the outcome of every request in a structured format. Cross-reference it with cache.log by timestamp to understand context. The default native log format is:

timestamp  duration  client  result/status  bytes  method  url  user  hierarchy  type

Example line showing a denied CONNECT:

1715348021.847      1 192.168.1.55 TCP_DENIED/403 4043 CONNECT api.example.com:443 - HIER_NONE/- text/html

The result field format is cache-result/HTTP-status. Common result codes to know:

  • TCP_DENIED — blocked by an ACL before Squid attempted a connection
  • TCP_MISS — cache miss, fetched from origin
  • TCP_MEM_HIT — served directly from RAM cache
  • HIER_NONE — no upstream peer; Squid either denied or served itself

When access.log shows TCP_DENIED, pivot to cache.log at the same second and search for the client IP to find the ACL trace.

Step 6 — Trace a Failed Request End-to-End

Use grep with the client IP and a narrow time window:

grep '192.168.1.55' /var/log/squid/cache.log | grep '14:32:0'

For SSL bump failures, the relevant section is 83. Look for lines mentioning the server hostname and phrases like ssl error, certificate verify failed, or handshake:

grep -E '83,[0-9]|ssl_error|certificate' /var/log/squid/cache.log | tail -50

For DNS-related failures, section 33 at level 5 will show whether Squid received NXDOMAIN, timed out, or returned a stale cached answer:

grep '33,' /var/log/squid/cache.log | grep -i 'fail\|timeout\|nxdomain'

Step 7 — Turn Debug Logging Off

Once you have your answer, restore the default immediately. Edit squid.conf to remove or comment out the elevated debug_options line, then restart:

sudo systemctl restart squid

Rotate the log to start clean and reclaim disk space:

sudo squid -k rotate

Verification

Confirm that Squid is running cleanly and that debug output is no longer flooding the log:

systemctl status squid
sudo wc -l /var/log/squid/cache.log

After a restart with ALL,1, a quiet proxy should add only a handful of lines per minute to cache.log. If the count is climbing fast, debug_options is still elevated.

Troubleshooting

cache.log is empty or not updating

Check that cache_log in squid.conf points to a writable path and that the Squid process owns it. Run sudo squid -N -d1 in the foreground to verify startup errors before they are swallowed by systemd.

Log file grows to tens of GB in minutes

You have a high-traffic proxy with a section at level 9. Drop back to level 5 or narrow the section list. Consider redirecting debug output to a ramdisk (tmpfs) during testing if disk I/O is a constraint.

ACL trace shows ALLOW but request still fails

The denial may be at the peer or origin server, not in Squid itself. Check access.log for HIER_DIRECT vs HIER_NONE and raise section 11 (HTTP client side) to level 5 to inspect the full request/response exchange.

debug_options line is ignored after reload

Some Squid builds require a full restart (not just squid -k reconfigure) for debug_options to take effect. Always use systemctl restart squid when changing this directive.

tested on:Ubuntu 22.04Debian 12Rocky 9Arch rolling

Frequently asked questions

What is the difference between debug level 5 and level 9?
Level 5 logs significant decision points such as ACL match results and connection state changes. Level 9 logs every internal function call in the section — useful for deep bugs but extremely verbose; on a busy proxy it can write gigabytes per minute.
Can I enable debug logging without restarting Squid?
You can send SIGUSR2 to toggle debug output in some builds, and 'squid -k reconfigure' re-reads most directives. However, debug_options is not reliably applied without a full restart, so systemctl restart is recommended.
How do I find the section number for a specific Squid feature?
The Squid project maintains a list at https://wiki.squid-cache.org/KnowledgeBase/DebugSections. You can also grep the Squid source (debugs(XX, Y, ...)) for the file corresponding to the feature you are investigating.
Why does access.log show TCP_DENIED/403 but cache.log shows nothing useful?
Your debug_options level is probably still at ALL,1. Raise sections 20 and 28 to level 5 and reproduce the request; the ACL evaluation trace will then appear in cache.log with matching timestamps.
Is it safe to use debug_options in production?
Briefly, yes — using a targeted section at level 5 on a low- to medium-traffic proxy causes acceptable overhead. Avoid ALL,9 in production entirely; it creates a serious disk and performance risk within minutes on any reasonably loaded system.

Related guides