jeessy2/ddns-go · error

API error

Error message

API error: %s

What it means

getDomainID receives a valid API response but its 'code' field is non-zero, meaning the DNSMgr API rejected the request at the application level (e.g. auth failure, invalid parameters). The server's message (apiResp.Msg) is surfaced verbatim.

Solutions

  1. Read apiResp.Msg in the error text — it states the server's reason
  2. Regenerate the API token in DNSMgr and update DNS.Secret in ddns-go config
  3. Confirm the token's account owns or can access the configured domain
  4. If a self-hosted DNSMgr changed its response codes, align the client with the new API contract

Example fix

// before (log)
failed to get domain ID: API error: unauthorized: token expired
// after
DNS.Secret: "<newly generated token>"  # update in ddns-go config and restart
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: verify the token is accepted before scheduling updates
req, _ := http.NewRequest("GET", base+"/api/domains?page=1&pageSize=1", nil)
req.Header.Set("Authorization", "Bearer "+apiToken)
resp, err := http.DefaultClient.Do(req)
if err != nil { return err }
var r struct{ Code int `json:"code"`; Msg string `json:"msg"` }
json.NewDecoder(resp.Body).Decode(&r)
resp.Body.Close()
if r.Code != 0 { return fmt.Errorf("token rejected: %s", r.Msg) }

Try / catch

if err != nil && strings.Contains(err.Error(), "API error") {
    msg := extractAfter(err.Error(), "API error: ")
    if strings.Contains(strings.ToLower(msg), "unauthor") || strings.Contains(msg, "token") {
        regenerateToken() // token invalid/expired
    }
    return // surface server message; don't blind-retry
}

Prevention

When it happens

Trigger: GET /domains?page=1&pageSize=1&keyword=<domain> returns code != 0: invalid/expired Bearer token, insufficient permissions, or server-side rejection of the keyword query.

Common situations: Rotated or revoked API token still configured in ddns-go; token from a different DNSMgr account that cannot see the domain; DNSMgr server returning code 401/403-style app errors after a version upgrade.

Related errors


AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03). Data as JSON: /api/errors/8de6b3247632acd3. Report an issue: GitHub.

Appendix: source

Thrown at dns/hipmdnsmgr.go:240

		return nil, err
	}

	return &apiResp, nil
}

// getDomainID Get domain ID
// Prefer using keyword parameter for direct query, with list matching as fallback
func (h *HiPMDnsMgr) getDomainID(baseURL, apiToken, domainName string) (int, error) {
	// Method 1: Use keyword parameter for direct query (efficient)
	path := fmt.Sprintf("/domains?page=1&pageSize=1&keyword=%s", domainName)

	apiResp, err := h.request(baseURL, apiToken, "GET", path, nil)
	if err != nil {
		return 0, err
	}

	if apiResp.Code != 0 {
		return 0, fmt.Errorf("API error: %s", apiResp.Msg)
	}

	var domains []DnsMgrDomain

	// Smart detection: support both array and object formats
	var rawData interface{}
	if err := json.Unmarshal(apiResp.Data, &rawData); err != nil {
		return 0, fmt.Errorf("failed to parse response data: %w", err)
	}

	switch v := rawData.(type) {
	case []interface{}:
		jsonData, _ := json.Marshal(v)
		if err := json.Unmarshal(jsonData, &domains); err != nil {
			return 0, fmt.Errorf("failed to parse domain list: %w", err)
		}
	case map[string]interface{}:
		if listData, ok := v["list"]; ok {

View on GitHub (pinned to 5874c2e666)