AdguardTeam/AdGuardHome · error

invalid blocked services: %w

Error message

invalid blocked services: %w

What it means

Converting an incoming client JSON object to a client object failed because the blocked-services schedule/IDs copied from the request are invalid. The wrapped error details the schedule validation problem.

Source

Thrown at internal/home/clientshttp.go:165

		upsCacheSize = prev.UpstreamsCacheSize
	}

	if cj.IgnoreQueryLog != aghalg.NBNull {
		ignoreQueryLog = cj.IgnoreQueryLog == aghalg.NBTrue
	}

	if cj.IgnoreStatistics != aghalg.NBNull {
		ignoreStatistics = cj.IgnoreStatistics == aghalg.NBTrue
	}

	if cj.UpstreamsCacheEnabled != aghalg.NBNull {
		upsCacheEnabled = cj.UpstreamsCacheEnabled == aghalg.NBTrue
		upsCacheSize = cj.UpstreamsCacheSize
	}

	svcs, err := copyBlockedServices(cj.Schedule, cj.BlockedServices, prev)
	if err != nil {
		return nil, fmt.Errorf("invalid blocked services: %w", err)
	}

	if (uid == client.UID{}) {
		uid, err = client.NewUID()
		if err != nil {
			return nil, fmt.Errorf("generating uid: %w", err)
		}
	}

	return &client.Persistent{
		BlockedServices:       svcs,
		UID:                   uid,
		IgnoreQueryLog:        ignoreQueryLog,
		IgnoreStatistics:      ignoreStatistics,
		UpstreamsCacheEnabled: upsCacheEnabled,
		UpstreamsCacheSize:    upsCacheSize,
	}, nil
}

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Fetch the current list of valid blocked service IDs (GET /control/blocked_services/services) and use only those
  2. Validate the Schedule object against the expected weekly-schedule schema before sending
  3. Check the wrapped error message for the exact offending field

Example fix

// before
{"blocked_services": ["not_a_service"]}
// after
{"blocked_services": ["youtube","tiktok"]}
Defensive patterns

Strategy: validation

Validate before calling

// Fetch valid service IDs first and intersect
valid, _ := getBlockedServiceIDs()
req.BlockedServices = intersect(req.BlockedServices, valid)

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "invalid blocked services") {
        // refresh IDs and retry once
    }
}

Prevention

When it happens

Trigger: POST/PUT /control/clients (add/update) with a BlockedServices list containing unknown service IDs or a malformed Schedule (bad ranges, unsupported day/hour values).

Common situations: Client code sending stale or invented service IDs after an upgrade removed/renamed them; hand-crafted JSON payloads; timezone/schedule format mistakes.

Related errors


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