jeessy2/ddns-go · error
生成签名失败: %v
Error message
生成签名失败: %v
What it means
Eranet.request signs every API call by building a sorted, percent-encoded canonical query string and computing an HMAC-SHA1 signature with Secret+'&'. If t.sign returns an error, request wraps it as '生成签名失败: %v' before any HTTP call is made, so create/modify/getRecordList abort immediately. In practice this signals a problem preparing the signed request rather than an API rejection.
Source
Thrown at dns/eranet.go:252
// 6. 重新构造最终的查询字符串(包含签名)
keys = append(keys, "Signature")
sort.Strings(keys)
var finalQuery []string
for _, k := range keys {
encodedKey := util.PercentEncode(k)
encodedValue := util.PercentEncode(params[k])
finalQuery = append(finalQuery, encodedKey+"="+encodedValue)
}
return strings.Join(finalQuery, "&"), nil
}
func (t *Eranet) request(apiPath string, params map[string]string, method string) ([]byte, error) {
// 生成签名
queryString, err := t.sign(params, method)
if err != nil {
return nil, fmt.Errorf("生成签名失败: %v", err)
}
// 构造完整URL
baseURL := "https://www.eranet.com"
fullURL := baseURL + apiPath + "?" + queryString
// 创建HTTP请求
req, err := http.NewRequest(method, fullURL, nil)
if err != nil {
return nil, fmt.Errorf("创建请求失败: %v", err)
}
// 设置请求头
req.Header.Set("Accept", "application/json")
// 发送请求
client := t.httpClient
resp, err := client.Do(req)View on GitHub (pinned to 5874c2e666)
Solutions
- Check that the Eranet Secret (API secret key) is set and correct in the ddns-go provider config; fix or re-enter it.
- Inspect the wrapped %v detail — it names the underlying signing failure; fix that cause.
- Confirm the SecretId/Secret pair has no stray whitespace or newline from copy-paste.
- If it persists after config fixes, verify the ddns-go Eranet driver version matches the provider's current signing (HMAC-SHA1) requirements.
- Enable ddns-go logs and re-run a single record update to see the full wrapped error.
Example fix
// before DNS := config Secret: "" // empty -> signing fails // after Secret: "your-eranet-secret-key" // valid, trimmed value
Defensive patterns
Strategy: try-catch
Validate before calling
// Before calling the provider, verify required credentials are present
if t.DNS.Secret == "" {
return errors.New("Eranet Secret is empty; set it in ddns-go config before syncing")
} Try / catch
body, err := t.request(apiPath, params, "POST")
if err != nil {
if strings.Contains(err.Error(), "生成签名失败") {
// signing failed before any network call — do not retry; fix credentials/config
return fmt.Errorf("eranet signing error, check Secret config: %w", err)
}
return err // network/HTTP errors may be retryable
} Prevention
- Re-enter the Eranet Secret after any config export/import
- Trim whitespace/newlines from pasted keys
- Test one record update after credential changes before enabling automation
- Keep the ddns-go Eranet driver updated to match current provider signing rules
When it happens
Trigger: Any Eranet API call (create, modify, getRecordList) where the sign step fails — e.g. misconfigured/empty DNS.Secret making the signing key invalid, or a failure building the canonicalized query parameters.
Common situations: Missing or malformed Eranet Secret key in ddns-go config; unexpected characters in params interacting with percent-encoding; a code change to sign() introducing an error path; empty credential fields after a config migration.
Related errors
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/d86df58d93702643.
Report an issue: GitHub.