jeessy2/ddns-go · error
API请求失败,状态码: %d, 响应: %s
Error message
API请求失败,状态码: %d, 响应: %s
What it means
Thrown by Eranet.request when the eranet.com API returns an HTTP status code other than 200. The error includes the numeric status and the raw response body, so the API's own error payload (often JSON explaining auth/signature problems) is embedded in the message. Affects create, modify, and getRecordList.
Source
Thrown at dns/eranet.go:284
req.Header.Set("Accept", "application/json")
// 发送请求
client := t.httpClient
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("请求失败: %v", err)
}
defer resp.Body.Close()
// 读取响应
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("读取响应失败: %v", err)
}
// 检查HTTP状态码
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API请求失败,状态码: %d, 响应: %s", resp.StatusCode, string(body))
}
return body, nil
}
View on GitHub (pinned to 5874c2e666)
Solutions
- Read the embedded response body in the error message — it usually states the API-level cause
- Verify the API key/secret configured for the eranet provider are correct and active
- Check system time (NTP) — the request Signature depends on timestamps and fails on skew
- If status is 5xx, retry later — it is an eranet-side outage
- Compare parameter values (domain, subdomain, record type) against eranet API docs
Example fix
// before
// opaque handling of error
return err
// after
var apiErr struct {
Code int `json:"code"`
Msg string `json:"message"`
}
if json.Unmarshal(body, &apiErr) == nil && apiErr.Msg != "" {
return fmt.Errorf("API请求失败,状态码: %d, 原因: %s", resp.StatusCode, apiErr.Msg)
} Defensive patterns
Strategy: try-catch
Validate before calling
// validate credentials & params before calling the API
if apiKey == "" || apiSecret == "" {
return fmt.Errorf("eranet credentials missing")
}
if strings.TrimSpace(domainName) == "" {
return fmt.Errorf("domain name required")
} Type guard
func isEranetStatusError(err error) (statusCode int, body string, ok bool) {
// "API请求失败,状态码: %d, 响应: %s"
const prefix = "API请求失败,状态码: "
msg := err.Error()
i := strings.Index(msg, prefix)
if i < 0 {
return 0, "", false
}
rest := msg[i+len(prefix):]
j := strings.Index(rest, ", 响应: ")
if j < 0 {
return 0, "", false
}
code, e := strconv.Atoi(strings.TrimSpace(rest[:j]))
if e != nil {
return 0, "", false
}
return code, rest[j+len(", 响应: "):], true
} Try / catch
_, err := eranetClient.GetRecordList(domain)
if err != nil {
if code, body, ok := isEranetStatusError(err); ok {
switch {
case code == 401 || code == 403:
return fmt.Errorf("check eranet API credentials: %s", body)
case code >= 500:
return retryWithBackoff(3, func() error { _, err = eranetClient.GetRecordList(domain); return err })
default:
return fmt.Errorf("eranet rejected request (%d): %s", code, body)
}
}
return err
} Prevention
- Always log the full error — the API response body inside it names the real cause
- Verify API key/secret in config and rotate expired tokens
- Keep the host clock NTP-synced (HMAC Signature validity depends on it)
- Cross-check domain/subdomain/record-type values against eranet API docs
- Treat 5xx as retryable and 4xx as configuration bugs
When it happens
Trigger: Any non-200 response from https://www.eranet.com: 401/403 for bad API credentials, 4xx for invalid parameters or signature mismatch, 5xx for eranet server errors, or 404 from a wrong apiPath.
Common situations: Wrong or expired eranet API key/secret in config; system clock skew breaking the HMAC Signature; parameter values rejected by the API (invalid domain/record); eranet service outage returning 5xx.
Related errors
- dnsla 请求失败,状态码: %d, 响应: %s
- dnsla 记录列表请求失败,状态码: %d, 响应: %s
- API请求失败,状态码: %d, 响应: %s
- 创建 dnsla 请求失败: %w
- 请求 dnsla 失败: %w
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/3a373a9f7d28c261.
Report an issue: GitHub.