Skip to main content
CleanWeb
Pi-hole

Add a local list to Pi-hole — carefully.

Pi-hole installs lists through its adlist and gravity workflow. This guide covers the domain-only CleanWeb output, local file permissions, rebuilding gravity, and the fallback path when the web interface rejects file:/// addresses.

There is no file-upload button

Pi-hole does not accept a generic file upload in its list UI. It consumes adlists by address. The address can be an HTTP(S) URL or, where supported, a local file:/// path. This is a different workflow from editing a hosts file.

Before you start

You need a working Pi-hole installation, access to its admin interface, and either SSH or another way to place a file on the Pi-hole host. If Pi-hole runs in Docker, copy the file into a mounted volume and use the path as seen inside the container.

Generate a Pi-hole configuration and download it first. The generated file uses one hostname per line. That format is accepted by Pi-hole's gravity parser and is easier to inspect than a hosts file.

Menu labels differ between Pi-hole v5 and v6. In v6, list management is generally under Settings → Lists. Older interfaces used Group Management → Adlists. Local-file handling has also varied between releases, so the fallback below matters.

What the CleanWeb file contains

The Pi-hole output is a domain-only list: one hostname per line, with # comment lines at the top. It does not start each line with 0.0.0.0, and it does not contain AdGuard modifiers or browser cosmetic rules.

# CleanWeb configuration
# Target: Security | Strength: Balanced | Format: Pi-hole
# Generated: [timestamp]
# Domains: [count]
# Sources: ...
#
# Coverage: bounded starter snapshot.
#
example.org
example.net

Pi-hole v6 can also parse ABP-style ||domain^ entries. CleanWeb deliberately emits the simpler domain list so the output does not depend on that newer parser path. Keep the list as one format; do not merge a hosts file, a domain list, and AdGuard rules into one file and assume they behave the same way.

Exact domains do not imply subdomains

Pi-hole treats a plain domain entry as an exact domain. Blocking example.org does not automatically block ads.example.org. This differs from AdGuard's ||example.org^ rule, which covers subdomains. If you need subdomain coverage in Pi-hole, add the exact subdomains or create a separate Pi-hole wildcard/regex rule and review it carefully.

A hostname in a domain list is not a regular expression. CleanWeb emits exact hostnames from its snapshot; it does not silently convert them into wildcard rules. For Pi-hole regex syntax, see the official documentation.

Add the list to Pi-hole

  1. Move the file to the Pi-hole machine. Pick a permanent location you control, such as your home directory. The path below is only an example: /home/pi/cleanweb.txt.
  2. Make sure Pi-hole can read it. The gravity process runs as the Pi-hole service account. On a typical install, a world-readable file works, for example chmod 644 /home/pi/cleanweb.txt. Do not make a directory world-writable or expose it through an unnecessary network share.
  3. Open Settings → Lists (or the equivalent in your version) and add a new list. Use a clear comment such as “CleanWeb Security Balanced.”
  4. Enter the adlist address. For a local file, use an absolute path with the file:// scheme and three slashes, for example file:///home/pi/cleanweb.txt. The third slash belongs to the filesystem root.
  5. Save the list. Some Pi-hole v6 releases have shown problems accepting file:/// addresses through the web UI. If your version rejects the path, do not edit the gravity database by hand. Use the URL fallback described below or consult the documentation for your release.
  6. Rebuild gravity. Adding the address does not load the domains by itself. Use Tools → Update Gravity or run pihole -g on the host.

Fallback: use a private URL

If local paths do not work reliably in your version, publish the text file from a web server reachable by the Pi-hole host and add that URL as the adlist. The URL must return the raw text file, not an HTML directory listing. Restrict access to your own network and prefer HTTPS. Do not put the file behind an authentication prompt that Pi-hole cannot satisfy, and do not expose a directory listing to the public internet.

Do not hand-edit gravity.db

Pi-hole manages its gravity database and list cache itself. Direct database edits can be overwritten or leave the UI inconsistent. If the supported workflow fails, use a URL or the documentation for your version rather than inventing a database change.

What “rebuild gravity” does

A gravity rebuild downloads or reads every enabled adlist, parses hostnames, and creates the compiled blocking tables. This is when your new file actually takes effect. Large lists use memory and can take time. If the rebuild fails, Pi-hole reports the failing list; read that message before changing unrelated settings.

After a successful update, check the list's domain count. If it is zero or obviously wrong, the file was empty, unreadable, or parsed differently than expected. Validate the text locally with the rule validator before changing Pi-hole.

Verify before relying on it

  • Confirm that client devices use Pi-hole as their DNS resolver. A router that hands out another DNS server, a VPN, or browser secure DNS can bypass Pi-hole entirely.
  • Check Pi-hole's query log while using a device on the network. Test a hostname that is definitely in the list and safe to fail.
  • If the list is enabled but you see no blocked queries, investigate client DNS settings and the gravity update result before assuming the list is wrong.

Updating the list

Replace the file on the Pi-hole host with a newly generated version, then rebuild gravity again. If you serve the file from a URL, replace the published file and rebuild gravity. Keep the same domains list address so Pi-hole does not accumulate stale entries.

Compare the download with the version currently deployed before replacing it. The rule diff normalizes hostnames across formats and shows additions, removals, duplicates, and unchanged rules.

Troubleshooting

“Invalid protocol” or the local address is rejected

Local path support is the least consistent part of this workflow across Pi-hole releases. Verify the path is absolute and the file is readable by the Pi-hole account, then use a private raw-text URL if your UI still refuses file:///. Check the official documentation rather than patching the database manually.

Gravity succeeds but the domains are not blocked

Check whether clients use Pi-hole, whether another DNS server is advertised by DHCP, and whether the operating system or browser has its own secure DNS setting. Query logs are the fastest way to see whether the device reaches Pi-hole at all.

A needed site stops working

Disable the CleanWeb list temporarily, then add a precise allowlist entry for the domain involved. Avoid disabling blocking for broad popular domains as a shortcut; that can undo much of the list's value.

Limits and safety

Pi-hole is a DNS sinkhole, not a content scanner. It cannot see the inside of encrypted traffic or stop a client that ignores it. A domain list may be incomplete or contain a false positive. CleanWeb's source categories are bounded snapshots; the source header links to the complete upstream list.

Review the source and license metadata before redistributing a generated list. For parser behavior and current UI details, rely on the official Pi-hole documentation and the release notes for your installed version.