Updating GeoIP and GeoSite Databases: Diagnosing and Fixing Broken Routing Rules
Suddenly seeing domestic sites routed through the proxy, or an overseas service getting classified as direct? In most cases it's not a bad rule — it's an outdated local GeoIP/GeoSite database. This article covers how these two geo databases work, how to update them manually and automatically, and the order of checks to run when rules still don't behave after updating.
What GeoIP and GeoSite actually are
Clash-family config files commonly include rules written like this:
rules:
- GEOIP,CN,DIRECT
- GEOSITE,google,Proxy
- GEOSITE,cn,DIRECT
- MATCH,Proxy
GEOIP,CN and GEOSITE,google above aren't judgments the core makes on its own — they're lookup results from a table. That table is one of two pre-compiled geo databases:
- GeoIP database (typically named
Country.mmdborgeoip.dat): maps global IP ranges to country/region codes. When the core receives a destination IP, it looks it up in this table to get a code likeCN,US, orHK, then matches that against the rules to decide direct or proxy. - GeoSite database (typically named
geosite.datorgeosite.db): groups common domains or domain suffixes into preset categories such ascn,google,github, ornetflix. A match against a category triggers the corresponding policy.
Both databases are static files maintained by the community, recompiled and released on a regular cadence by upstream projects (such as Loyalsoldier's rule sets or v2fly's domain-list-community). They don't update automatically when the core is upgraded, and switching subscriptions doesn't refresh them either. Think of them as a dictionary — whether a lookup succeeds depends entirely on when that dictionary was printed.
Why an outdated database breaks routing accuracy
IP range allocation and domain ownership on the internet are never static: cloud providers expand or migrate IP pools, CDN nodes get rebalanced across regions, and newly launched domains simply aren't in any category yet. If your local database is months — or even a year or two — behind, two typical symptoms show up:
- Traffic that should go direct gets proxied instead: a local site switches to a new IP range or a new CDN, the old GeoIP database can't resolve it to
CN, the rule match fails, and it falls through to the default policy (usually proxy) — showing up as noticeably slower access or occasional connection failures. - Traffic that should be proxied gets sent direct instead: an overseas service switches domains or adds new subdomains that aren't in the old GeoSite category, so no rule matches, and a catch-all like
MATCH,DIRECTtakes over — exposing that traffic on a network with no proxy at all.
Note: the rule file itself hasn't changed at all — it's the underlying lookup database that's stale. This kind of issue is often misdiagnosed as "the subscription is broken" or "the rule is written wrong," and chasing the wrong lead wastes a lot of time.
Confirm the current database version and update time first
Before making any changes, confirm the problem is actually the database. Different clients expose this differently, but the approach is the same: find the database file's last-modified time and compare it against the upstream release history.
- In the client's "core/rules" settings page, you can usually see the local path and last-update timestamp for the GeoIP and GeoSite files; some clients even display a version number or the first few characters of a commit hash.
- If the client's UI doesn't expose this, go directly into the config directory and check the modification date of
Country.mmdbandgeosite.dat— on Android this is usually under adataorgeosubdirectory inside the app's private storage. - Compare against the upstream repository's release dates (GeoIP and GeoSite databases are typically updated weekly or biweekly). If your local files are over a month behind, it's safe to assume a manual refresh is needed.
A more direct way to verify: temporarily add an explicit domain or IP rule pointing at a target you suspect is being misrouted, and watch whether it hits the catch-all instead of the expected category — if the explicit rule works but the geo rule doesn't, the problem is almost certainly the database itself.
Steps to manually update the databases
The core idea behind a manual update: download the latest compiled database files from a trusted rule-set repository, replace the old files in the client's config directory, then restart the core or reload the config.
- Confirm which core your client is running: stock Clash, Clash Meta, and mihomo don't all require exactly the same database file format — mihomo supports more granular rule-set formats in some versions — so check which file types (
.mmdb/.dat/.db) your current core can actually read before replacing anything. - Get the latest database files: download the newest release from the corresponding upstream rule-set project's release page. Keep the filenames consistent with what's specified in
geodata-url,geoip-url, or the local path in your config — a mismatched filename means the client keeps reading the old file. - Replace the local files: drop the downloaded files into the same location as the originals in the client's config directory. Back up the old files first, in case the new ones turn out to be corrupted and you need to roll back.
- Restart the core or reload the config: most clients need the proxy service restarted after a file swap for the database to be reloaded — simply refreshing a subscription or switching nodes usually doesn't trigger a database reload.
- Verify it worked: after restarting, revisit a site that was previously misrouted, or check the client's connection log for the rule name that request actually hit, to confirm it now lands in the expected category.
# Example using the mihomo command-line core: a typical manual replace-and-reload sequence
# 1. Stop the running service
systemctl stop mihomo
# 2. Overwrite the old GeoIP / GeoSite databases with the new files
cp Country.mmdb /etc/mihomo/Country.mmdb
cp geosite.dat /etc/mihomo/geosite.dat
# 3. Start it back up
systemctl start mihomo
Configuring auto-update to avoid repeated staleness
A manual update solves the problem once, but the database will go stale again after a while. A more reliable approach is to declare the database's remote URL and update interval in the config, letting the client pull the latest version automatically on startup or on a schedule.
For cores that support this field, the config typically looks something like this:
geodata-mode: true
geo-auto-update: true
geo-update-interval: 24
geox-url:
geoip: "https://example.com/Country.mmdb"
geosite: "https://example.com/geosite.dat"
geo-auto-update: whether the core is allowed to check for and download new database versions in the background.geo-update-interval: the check interval in hours. Setting it too short just adds unnecessary network requests — checking every 24 hours is generally enough to keep pace with upstream releases.geox-url: the download source for the databases. If the default source is slow on your network, you can point it at a mirror, but check how promptly that mirror syncs — otherwise you're just serving stale data from a different location.
Not every client GUI exposes toggles for these fields. If yours doesn't, you can add them directly as text under "Edit Config File" or "Advanced Settings," then restart the service for them to take effect.
What to check if rules still don't work after updating
If you've confirmed you downloaded the latest database and the problem persists after replacing it, work through the following checks in order — this usually narrows it down to a specific stage.
- Confirm the file was actually replaced: check whether the modification time and file size actually changed. Some clients cache the database in multiple locations (e.g., the install directory alongside the user config directory) — replacing the wrong copy is the same as not replacing it at all.
- Confirm the core actually reloaded the file: some clients' "restart" button only restarts the UI process, not the underlying core service — you may need to fully stop and restart the process or service at the system level.
- Check whether an earlier rule is intercepting the match: Clash rules are matched top-to-bottom in order. If there's an overly broad rule (say, a loose
DOMAIN-SUFFIXorIP-CIDR) placed beforeGEOSITE,cn,DIRECT, the request gets matched early and never reaches the geo rule at all. - Check whether your subscription overrides the local rule-set config: if you're using a config generated by a "subscription conversion" service, some conversion rules bake in their own geo data source URL at generation time — meaning the file you manually replaced locally might never be referenced.
- Check the connection log for the actual matched rule name: most clients offer a live log or connection panel showing exactly which rule each request matched. This is the most direct way to tell whether the issue is the database or the rule order.
Tip: open the connection log and compare entries one by one first — it's far more efficient than guessing at rule syntax, and most "misrouting" issues can be seen directly in the log as the rule that actually matched.
Building a long-term maintenance habit
Geo database staleness is an ongoing issue, not something you fix once and forget. A few habits worth building to reduce the odds of hitting this again:
- After enabling auto-update, periodically check the database's actual update timestamp manually — an auto-update task can fail silently due to a network hiccup without any obvious sign.
- When switching subscription or rule-set sources, check whether they bundle their own geo data source URL, so it doesn't conflict with what you're manually maintaining locally.
- Before making major rule file changes, test them in a separate environment or a standalone config group before merging into your daily config, to avoid widespread routing disruptions in production.
- Keep an eye on the upstream rule-set project's changelog, especially during periods when commonly used domestic services undergo large-scale IP range migrations or domain restructuring — a manual refresh right then is more reliable than waiting for the next scheduled auto-update.