wtfutil/wtf · error

only Pi-hole API version 3 is supported version %d was det

Error message

 only Pi-hole API version 3 is supported
 version %d was detected

What it means

Version compatibility guard in checkServer: after querying the Pi-hole API, the returned version field is not 3. The module only understands API v3, so with Pi-hole v5+ or v6 instances (which ship different API versions/endpoints) the widget refuses to proceed rather than misparse responses.

Source

Thrown at modules/pihole/client.go:344

			resp.StatusCode)
	}

	var vResp struct {
		Version int `json:"version"`
	}

	var rBody []byte

	if rBody, err = io.ReadAll(resp.Body); err != nil {
		return fmt.Errorf(" Pi-hole server failed to respond\n %s", parseError(err))
	}

	if err = json.Unmarshal(rBody, &vResp); err != nil {
		return fmt.Errorf(" invalid response returned from Pi-hole Server\n %s", parseError(err))
	}

	if vResp.Version != 3 {
		return fmt.Errorf(" only Pi-hole API version 3 is supported\n version %d was detected", vResp.Version)
	}

	return err
}

func (widget *Widget) adblockSwitch(action string) {
	var req *http.Request

	var url *url2.URL
	url, _ = url2.Parse(widget.settings.apiUrl)

	var query url2.Values
	query, _ = url2.ParseQuery(url.RawQuery)

	query.Add(strings.ToLower(action), "")
	query.Add("auth", widget.settings.token)

	url.RawQuery = query.Encode()

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Use a Pi-hole instance exposing API version 3 (or an older Pi-hole release)
  2. Check for an updated wtfutil version supporting newer Pi-hole APIs
  3. Pin the Pi-hole version or expose a v3-compatible endpoint proxy

Example fix

// before: unsupported Pi-hole v6 API
// after: run a compatible Pi-hole (FTL v5.x) or upgrade the widget
// check locally:
// curl http://pi.hole/admin/api.php?version  -> {"version":3}
Defensive patterns

Strategy: validation

Validate before calling

var v struct{ Version int `json:"version"` }
resp, err := http.Get(apiURL + "?version")
if err == nil {
    if json.NewDecoder(resp.Body).Decode(&v) == nil && v.Version != 3 {
        log.Printf("Pi-hole API version %d detected; widget needs version 3", v.Version)
    }
}

Try / catch

if err := widget.checkServer(*client, apiUrl); err != nil {
    if strings.Contains(err.Error(), "only Pi-hole API version 3") {
        log.Printf("upgrade/downgrade Pi-hole or the widget: %v", err)
    }
}

Prevention

When it happens

Trigger: vResp.Version != 3 in checkServer after a successful parse of the '<apiUrl>?version' response.

Common situations: Pi-hole was upgraded to a release exposing a newer API version, or the endpoint sits behind a proxy that alters the response, or a non-Pi-hole service happens to answer on that URL.

Related errors


AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03). Data as JSON: /api/errors/26a75113dd55ff13. Report an issue: GitHub.