Guide 08
Debugging guide
Diagnose and fix common problems with the local evaluation stack.
This guide collects problems you may hit when running the Mega2 evaluation stack locally. Each problem follows the same order: symptoms, how to confirm the cause, the cause, and the fix. Confirm the cause with the commands below before you change any configuration. To start the stack, see the Quick Start.
1. Where to start
Find out which service is not running, then read its logs:
COMPOSE=macos-orbstack-mega2-compose.yml # macOS with OrbStack
COMPOSE=linux-mega2-compose.yml # Linux Docker
docker compose -f $COMPOSE ps -a # status and exit code of each service
docker compose -f $COMPOSE logs --tail 100 mega2 # recent mega2 logs
On startup, mega2 applies database migrations, initializes an empty Monorepo, and writes the initial Git objects to RustFS. If any step fails, the process exits with code 1 and the last log lines state the reason. Monorepo initialization runs in a single database transaction and is rolled back as a whole on failure; once the cause is fixed, run docker compose -f $COMPOSE up -d --wait again. There is no need for down -v.
2. macOS with OrbStack: mega2 fails to start while Clash Verge Tun Mode is on
2.1. Symptoms
- After
docker compose -f macos-orbstack-mega2-compose.yml up -d --wait, postgres, redis, rustfs, and rustfs-init are all healthy, but mega2 exits a few seconds after it starts (Exited (1)). Runningupagain gives the same result. - The mega2 logs show repeated object storage retries and end with a failed Git object write:
INFO object_store::client::retry: Encountered transport error of kind Request, backing off for 0.14486904 seconds, retry 3 of 10: HTTP error: error sending request
...
Other error: object_storage::put_many failed for key=afff6026cbd0c96177c593ff71f92a563f354c3b namespace=git error_chain:
[0] ObjectStore { message: "Generic S3 error: Error performing PUT http://mega2-rustfs.orb.local:9000/mega2/git/af/ff/60/26cbd0c96177c593ff71f92a563f354c3b in 3.44620306s, after 10 retries, max_retries: 10, retry_timeout: 180s - HTTP error: error sending request", not_found: false }
- Clash Verge is running on the host with Tun Mode enabled.
2.2. Confirm the cause
Resolve the RustFS host name on the host and inside a container:
dscacheutil -q host -a name mega2-rustfs.orb.local # host
docker exec mega2-rustfs getent hosts mega2-rustfs.orb.local # inside a container
Normally both return an address assigned by OrbStack (for example 192.168.138.5). If the result falls in 198.18.0.0/15 (for example 198.18.0.16), or is the proxy's IPv6 fake-ip address (for example 2001:2::5), the proxy's fake-ip DNS has taken over the name. To confirm further:
ifconfig | grep 'inet 198.18.' # the Clash TUN interface, e.g. inet 198.18.0.1
dns-sd -G v4v6 mega2-rustfs.orb.local # watch for a few seconds, then press Ctrl-C
dns-sd lists two sets of answers. The set with IF 0 is the proxy's fake-ip and appears almost immediately; the other set comes from the OrbStack bridge (non-zero IF) about 100 ms later and holds the real address. Then reach RustFS through the real address. A 200 means RustFS itself is healthy and only name resolution is broken:
# Replace 192.168.138.5 with the real address shown by dns-sd
curl -s -o /dev/null -w '%{http_code}\n' \
--resolve mega2-rustfs.orb.local:9000:192.168.138.5 \
http://mega2-rustfs.orb.local:9000/health
2.3. Cause
- The macOS Compose file (
macos-orbstack-mega2-compose.yml) points mega2 at RustFS throughhttp://mega2-rustfs.orb.local:9000. The name resolves both on the host and inside containers, so artifact presigned URLs can also be downloaded directly from the host. The other services talk to each other by Compose service name (postgres,redis,rustfs), which Docker's embedded DNS resolves directly, so they are unaffected. That is why only mega2 fails. - On macOS, OrbStack answers
*.orb.localover mDNS. With Tun Mode on and DNS in fake-ip mode, Clash Verge takes over the system's DNS queries and immediately answers this name with a fake-ip, ahead of OrbStack's real answer. DNS queries from inside containers are also resolved by the host in the end, so they get the same fake-ip. - Connections to the fake-ip enter the proxy core, which cannot deliver them to the OrbStack container, so they are closed right away (curl reports
Empty reply from server). mega2 fails to write to RustFS while initializing the Monorepo and exits after 10 retries. - Clash Verge's default
fake-ip-filterincludes*.local, but in mihomo's domain wildcards*matches exactly one level: it matchesfoo.localbut notmega2-rustfs.orb.local.
2.4. Fix
Add +.orb.local to fake-ip-filter. + matches subdomains at any depth, so Clash stops assigning fake-ips to *.orb.local and the system uses the real address returned by OrbStack.
In Clash Verge Rev, append the entry with the global extend script: on the Profiles page, right-click Global Extend Script, choose Edit File, enter the script below, and save. Extend scripts run after DNS Overwrite, so the entry takes effect whether or not DNS Overwrite is enabled, and the existing filter entries are kept:
function main(config, profileName) {
config.dns = config.dns || {};
const filter = config.dns["fake-ip-filter"] || [];
if (!filter.includes("+.orb.local")) filter.push("+.orb.local");
config.dns["fake-ip-filter"] = filter;
return config;
}
If your global extend script already has a main function, merge the lines that modify config.dns into it. Do not write dns.fake-ip-filter in Global Extend Config (YAML) instead: since v2.5.5, a dns field written by an extend config replaces the original value as a whole, which drops all default filter entries (see the Clash Verge Rev documentation). If you edit the mihomo configuration file directly, add the same entry to the existing dns.fake-ip-filter list:
dns:
fake-ip-filter:
- '+.orb.local'
After saving, flush the macOS DNS cache, check the resolution, and start the stack again:
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
dscacheutil -q host -a name mega2-rustfs.orb.local # only the OrbStack address remains
docker exec mega2-rustfs getent hosts mega2-rustfs.orb.local # the same inside the container
docker compose -f macos-orbstack-mega2-compose.yml up -d --wait
As a stopgap, turn off Tun Mode in Clash Verge and use System Proxy only: after you flush the DNS cache, resolution recovers and you can bring the stack up. mega2 keeps talking to RustFS while it runs, though, so once Tun Mode is back on, pushes, LFS, and other operations that read or write objects fail again. Use the filter above as the lasting fix.
Other mihomo-based clients (such as Mihomo Party and FlClash) take the same +.orb.local entry in dns.fake-ip-filter. For Surge, sing-box, and other tools that use fake-ip, exclude *.orb.local and all of its subdomains from fake-ip as well.