txthinking/brook · warning
block ${addr}
Error message
block ${addr} What it means
The block plugin rejects a connection because the target hostname was found in the configured domain blocklist. brook.ListHasDomain checks the domain (lowercased, via the cache) against the user-supplied domain list, and when it matches, the dial is aborted with "block <addr>" instead of connecting.
Source
Thrown at plugins/block/block.go:160
var c6 []*net.IPNet
if bk.Lock != nil {
bk.Lock.RLock()
}
ds = bk.Domain
c4 = bk.CIDR4
c6 = bk.CIDR6
if bk.Lock != nil {
bk.Lock.RUnlock()
}
h, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
var a net.Addr
ip := net.ParseIP(h)
if ip == nil {
if brook.ListHasDomain(ds, strings.ToLower(h), bk.Cache) {
return nil, errors.New("block " + addr)
}
a, err = f(network, addr)
if err != nil {
return nil, err
}
v, ok := a.(*net.TCPAddr)
if ok {
ip = v.IP
}
if !ok {
ip = a.(*net.UDPAddr).IP
}
}
if brook.ListHasIP(c4, c6, ip, bk.Cache, bk.GeoIP) {
return nil, errors.New("block " + addr)
}
if a != nil {
return a, nilView on GitHub (pinned to 5cd13ef3b1)
Solutions
- Remove the target domain from the block domain list file (or its parent entry causing the match).
- Check the lowercased host "h" in the error message against list entries; broaden/narrow list patterns as intended.
- Restart brook after editing the list so the cache refreshes.
- If the domain should resolve but be IP-filtered instead, move it from the domain list to the IP list configuration.
Example fix
// before (list file) ads.example.com tracker.example.com // after: remove the entry that matches your needed domain # ads.example.com removed
Defensive patterns
Strategy: fallback
Validate before calling
// check membership before dialing
if brook.ListHasDomain(ds, strings.ToLower(host), cache) {
log.Printf("skipping blocked domain %s", host)
} Try / catch
if strings.HasPrefix(err.Error(), "block ") {
log.Printf("domain blocked by policy: %v", err)
// route via alternate proxy or surface a policy-denied result to the user
} Prevention
- Keep blocklists curated; review entries that are parent domains of needed hosts.
- Test new blocklist entries against the set of domains your apps use.
- Lowercase hostnames exactly as the plugin does when pre-checking.
- Document list file locations and restart procedures for operators.
When it happens
Trigger: A client requests a connection whose hostname is present in the domain blocklist file (or matches a list entry) while the brook server runs with the --blockDomainList option.
Common situations: Corporate/parental filtering setups where a legitimately requested domain happens to be on the blocklist; overly broad list entries (e.g., a parent domain) blocking subdomains; stale list entries after policy changes.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
AI-assisted analysis of txthinking/brook@5cd13ef3b1 (2026-09-06).
Data as JSON: /api/errors/8f02574fdcbec208.
Report an issue: GitHub.