glanceapp/glance · error
service must be one of: %s, %s, %s, %s
Error message
service must be one of: %s, %s, %s, %s
What it means
Returned by dnsStatsWidget.Initialize when widget.Service is not one of the four supported constants: adguard, pihole_v6 (dnsServicePiholeV6), pihole, technitium. It is a pure config-validation error raised at page load before any network activity.
Source
Thrown at internal/glance/widget-dns-stats.go:81
func (widget *dnsStatsWidget) initialize() error {
titleURL := strings.TrimRight(widget.URL, "/")
switch widget.Service {
case dnsServicePihole, dnsServicePiholeV6:
titleURL = titleURL + "/admin"
}
widget.
withTitle("DNS Stats").
withTitleURL(titleURL).
withCacheDuration(10 * time.Minute)
switch widget.Service {
case dnsServiceAdguard:
case dnsServicePiholeV6:
case dnsServicePihole:
case dnsServiceTechnitium:
default:
return fmt.Errorf("service must be one of: %s, %s, %s, %s", dnsServiceAdguard, dnsServicePihole, dnsServicePiholeV6, dnsServiceTechnitium)
}
return nil
}
func (widget *dnsStatsWidget) update(ctx context.Context) {
var stats *dnsStats
var err error
switch widget.Service {
case dnsServiceAdguard:
stats, err = fetchAdguardStats(widget.URL, widget.AllowInsecure, widget.Username, widget.Password, widget.HideGraph)
case dnsServicePihole:
stats, err = fetchPihole5Stats(widget.URL, widget.AllowInsecure, widget.Token, widget.HideGraph)
case dnsServiceTechnitium:
stats, err = fetchTechnitiumStats(widget.URL, widget.AllowInsecure, widget.Token, widget.HideGraph)
case dnsServicePiholeV6:
var newSessionID stringView on GitHub (pinned to 91324e8de7)
Solutions
- Set service to exactly one of: adguard, pihole, pihole_v6, technitium (lowercase).
- Check YAML indentation — service: must sit under the dns-stats widget, not a sibling key.
- After editing, reload the page/config; the error appears immediately on render.
Example fix
# before - type: dns-stats service: adguard-home # after - type: dns-stats service: adguard
Defensive patterns
Strategy: validation
Validate before calling
var validDNSServices = map[string]bool{
"adguard": true, "pihole": true, "pihole_v6": true, "technitium": true,
}
if !validDNSServices[widget.Service] {
return fmt.Errorf("dns-stats: service must be one of adguard, pihole, pihole_v6, technitium, got %q", widget.Service)
} Prevention
- Copy service values verbatim from the glance dns-stats docs.
- Use lowercase identifiers; no spaces or capitalization.
- Add a config-lint step that checks enumerated fields against allowlists.
When it happens
Trigger: Setting service: adguard-home, service: PiHole, service: nextdns, or omitting/changing the key in a dns-stats widget block.
Common situations: Guessing the service name instead of copying the docs; case mismatch; renaming after upgrading glance versions that changed accepted values.
Related errors
- widget 'type' property is empty or not specified
- unknown widget type: %s
- URL is required
- nested groups are not supported
- split columns inside of groups are not supported
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/ad18bb62d313ec9f.
Report an issue: GitHub.