jeessy2/ddns-go · error
生成签名失败: %v
Error message
生成签名失败: %v
What it means
Nowcn.request builds a signed query string via t.sign before every API call; if signing fails the error is wrapped in Chinese ('签名生成失败' = signature generation failed). This is a pre-flight failure — no HTTP request is made, so create/modify/getRecordList cannot proceed.
Source
Thrown at dns/nowcn.go:241
// 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 *Nowcn) 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://api.now.cn"
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
- Verify the Nowcn API key/secret are set and non-empty in configuration
- Check that sign() is receiving the expected method and params
- Log the underlying error from t.sign to pinpoint the missing credential
- Re-generate provider credentials if they were rotated/revoked
Example fix
// before
queryString, err := t.sign(params, method)
if err != nil {
return nil, fmt.Errorf("生成签名失败: %v", err)
}
// after (guard credentials before calling request)
if t.accessKey == "" || t.secretKey == "" {
return nil, errors.New("nowcn: accessKey/secretKey not configured")
}
queryString, err := t.sign(params, method)
if err != nil {
return nil, fmt.Errorf("生成签名失败: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
// Go: fail fast on missing credentials before any request
if t.accessKey == "" || t.secretKey == "" {
return errors.New("nowcn: accessKey and secretKey must be configured")
} Type guard
func (t *Nowcn) credentialsOK() bool {
return t.accessKey != "" && t.secretKey != ""
} Try / catch
body, err := nowcnClient.request(apiPath, params, "GET")
if err != nil {
if strings.Contains(err.Error(), "生成签名失败") {
return fmt.Errorf("signature failure — check nowcn credentials: %w", err)
}
return err
} Prevention
- Load and sanity-check credentials at startup, not per-request
- Never pass empty/nil params maps to sign
- Keep credential loading in one tested place
- Rotate and re-verify credentials after provider-side changes
When it happens
Trigger: t.sign returns an error — typically a missing/empty API key or secret in the Nowcn credentials, or an unsupported method passed to the signature algorithm.
Common situations: Credentials not loaded from config/environment (empty accessKey/secretKey), misconfigured provider credentials block, or a code path passing an unexpected HTTP method into sign.
Related errors
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/7c99d2cb97c5ce3d.
Report an issue: GitHub.