jeessy2/ddns-go · error
API error: %s
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.
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)
Solutions
- Read apiResp.Msg in the error text — it states the server's reason
- Regenerate the API token in DNSMgr and update DNS.Secret in ddns-go config
- Confirm the token's account owns or can access the configured domain
- 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
- Rotate and update the API token before expiry
- Verify the token belongs to the account owning the configured domains
- Log the full wrapped error to capture the server's apiResp.Msg
- After DNSMgr upgrades, re-run a smoke test of an authenticated GET /domains
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
- dnsla 请求失败,状态码: %d, 响应: %s
- failed to get domain ID: %w
- failed to get record: %w
- 创建 dnsla 请求失败: %w
- 请求 dnsla 失败: %w
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/8de6b3247632acd3.
Report an issue: GitHub.