AdguardTeam/AdGuardHome · error

getting ipsets from config line at idx

Error message

getting ipsets from config line at idx %d: %w

What it means

While parsing config line i, resolving the referenced ipset names against the ipsets known on the system failed — typically one of the names does not exist (see 'unknown ipset %q') or a header query failed.

Solutions

  1. Run 'ipset list' and verify each name in the config exists
  2. Create missing sets with 'ipset create <name> hash:ip family inet' or similar
  3. Persist ipsets across reboots (ipset save/restore, netfilter-persistent)

Example fix

# before
ipset list | grep blocklist   # missing
# after
ipset create blocklist hash:ip family inet
ipset save > /etc/ipset.conf
Defensive patterns

Strategy: validation

Validate before calling

func requiredSetsExist(conf []string) error {
	known := shellOut("ipset", "list", "-name")
	for _, line := range conf {
		for _, n := range strings.Split(strings.SplitN(line, "/", 2)[1], ",") {
			if !known[strings.TrimSpace(n)] { return fmt.Errorf("missing set %q", n) }
		}
	}
	return nil
}

Prevention

When it happens

Trigger: A config line references an ipset that was not returned by the initial list of sets and not created afterwards, so m.ipsets cannot find properties for it.

Common situations: Referencing an ipset before creating it with 'ipset create', a typo in the set name, or sets lost after reboot (not persisted).

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/bc7afd1d6528a69f. Report an issue: GitHub.

Appendix: source

Thrown at internal/ipset/ipset_linux.go:287

		return err
	}

	currentlyKnown := map[string]props{}
	for _, p := range all {
		currentlyKnown[p.name] = p
	}

	for i, confStr := range ipsetConf {
		var hosts, ipsetNames []string
		hosts, ipsetNames, err = parseIpsetConfigLine(confStr)
		if err != nil {
			return fmt.Errorf("config line at idx %d: %w", i, err)
		}

		var ipsets []props
		ipsets, err = m.ipsets(ctx, ipsetNames, currentlyKnown)
		if err != nil {
			return fmt.Errorf("getting ipsets from config line at idx %d: %w", i, err)
		}

		for _, host := range hosts {
			m.domainToIpsets[host] = append(m.domainToIpsets[host], ipsets...)
		}
	}

	return nil
}

// ipsetProps returns the properties of an ipset with the given name.
//
// Additional header data query.  See https://github.com/AdguardTeam/AdGuardHome/issues/6420.
//
// TODO(s.chzhen):  Use *props.
func (m *manager) ipsetProps(name string) (p props, err error) {
	// The family doesn't seem to matter when we use a header query, so
	// query only the IPv4 one.

View on GitHub (pinned to b41aefbe51)