跳到主要内容
ecdsa.com

错误码

调用失败时,API 返回 HTTP 状态码和 JSON 信封,其中的 code 说明出了什么问题。以下是 API 可能返回的全部 25 个错误码。v1 内可能会新增错误码:遇到未知的错误码时,按其 HTTP 状态码处理。

错误信封

所有错误响应体都是这种结构;code 和 message 始终存在。

字段类型必需说明
errorobject是
error.codestring是

Machine-readable error code. Each response lists the codes it can carry; new codes may be added within v1, so treat an unknown code by its HTTP status.

error.messagestring是

Human-readable explanation (English).

error.requestIdstring否

The X-Request-Id of this request — quote it when reporting a problem. Sent since v1.1.

error.detailobject否

Structured context for the error, such as the offending field; omitted when there is none.

  • 成员名任意
error.docsstring否

Where the error codes are explained. Sent since v1.1.

  • 格式 uri

真实的错误响应——请求中缺少必需字段:

curl
curl -sS 'https://ecdsa.com/api/v1/jwt/decode' \
  -H 'content-type: application/json' \
  -d '{}'
响应 400
{
  "error": {
    "code": "missing_field",
    "message": "Field \"token\" is required and must be a non-empty string.",
    "requestId": "docs-example",
    "docs": "https://ecdsa.com/developers#errors"
  }
}

全部错误码

错误码HTTP含义出现场景处理方法SDK
invalid_json400The body is not valid JSON or not a JSON object; or the input nests arrays and objects more than 64 levels deep (JSON documents inside string fields count too), or is too complex to inspect for private keys.

典型原因:请求体是表单编码或纯文本而不是 JSON,顶层是 JSON 数组或字符串,或者程序生成的输入嵌套过深。content-type 请求头无关紧要,关键在于请求体本身。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

以单个 JSON 对象作为请求体发送。如果输入是程序生成的,检查其嵌套深度。不重试
missing_field400A required field is absent or empty.

操作要求的字段缺失、为 null、为空或不是字符串——常见原因是字段名拼写不同,例如把 publicKey 写成了 public_key。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

补上错误消息中指出的字段;该操作的参考页面列出了所有必需字段。不重试
invalid_input400A field could not be parsed — the message explains exactly why.

字段存在但无法解析:密钥、签名、令牌或证书使用了该操作无法识别的编码或格式。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, Create a webhook endpoint

查看错误消息——其中会指出字段和原因。检查编码(十六进制、base64、PEM);如果是签名,还要检查曲线。不重试
private_key_rejected400The request contains private-key material (a PEM PRIVATE KEY block, an OpenSSH, SSH2 or PuTTY private key, or a JWK with "d"). Never send private keys anywhere.

在只需要公钥部分的地方粘贴了完整的密钥文件:PKCS#8 或 SEC1 PEM,OpenSSH 或 PuTTY 私钥,或者仍带有“d”的 JWK——嵌套在存放 JSON 的字符串中也算。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

只发送公开数据。需要处理私钥时,使用浏览器工具——它们在你的机器上运行,不发送任何数据。不重试
unsupported_algorithm400The token's algorithm is not one this operation verifies.

JWT 使用了该操作不验证的算法:HS*、RS*、PS*、EdDSA、ES256K 或 none。

操作: Verify an ES256/ES384/ES512 JWT signature

此 API 验证 ES256、ES384 和 ES512。使用其他算法的令牌请用 JWT 库在本地验证——切勿把 HMAC 密钥发送到任何地方。不重试
invalid_domain400Not a public DNS hostname (IP addresses, single-label names and paths are refused).

路径段是 IP 地址、不含点的名称(例如 localhost),或者不是主机名的文本。名称前后的协议、端口或路径会先被去掉。

操作: TLS signature-health grade for a domain

发送公网主机名,例如 github.com。IP 地址和内部名称无法从这里扫描。不重试
scan_dns_error400The domain does not resolve in public DNS.

在公共 DNS 中解析该名称失败:域名不存在(拼写错误、注册已过期,或者是只有内部 DNS 才能解析的名称),没有 A 或 AAAA 记录,或者 DNS 故障。

操作: TLS signature-health grade for a domain

检查拼写,并确认该名称有 A 或 AAAA 记录。不重试
scan_private_address400The domain resolves (at least partly) to a private or reserved address.

该名称的某个地址——IPv4、IPv6 或嵌入在 IPv6 中的 IPv4——位于私有或保留地址段,例如内部网络或环回地址。公有地址与私有地址混合时,会整体被拒绝。

操作: TLS signature-health grade for a domain

检测可以从公网访问的主机——内部主机无法从这里扫描。不重试
webhook_url_refused随 API 密钥推出400The webhook URL cannot receive deliveries: it is not https on port 443, its host is not a public DNS name, or the name does not resolve or resolves (at least partly) to a private or reserved address.

创建端点时使用了 http URL、443 以外的端口、IP 地址或内部名称,或者主机的 DNS 应答中包含私有或保留地址——即使多个地址中只有一个属于这种情况也会被拒绝。

操作: Create a webhook endpoint

使用默认端口、公网主机名的 https URL。错误消息会说明 URL 违反了哪条规则;如果是地址被拒绝,还会指出是哪个地址以及所属的地址段。不重试
unauthorized401The Authorization or X-API-Key header is malformed, the API key is not valid (wrong checksum, unknown, revoked or expired), or the operation needs a key.

存在 Authorization 或 X-API-Key 请求头但格式错误——API 密钥推出后,还包括未知、已吊销或已过期的密钥。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

去掉该请求头以匿名调用,或者发送完整且有效的密钥。不重试
forbidden_scope随 API 密钥推出403The API key is valid but lacks a scope this operation requires; the message names it.

密钥创建时没有包含操作所需的范围,例如只有 api 范围的密钥调用了需要 scan 范围的域名健康检查操作。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

使用具有该范围的密钥调用。不重试
webhook_limit_reached随 API 密钥推出403The account already has as many webhook endpoints as its plan allows.

账号已有的端点数量达到套餐上限后又创建端点;免费版允许一个。

操作: Create a webhook endpoint

删除不再需要的端点;如果要修改现有端点的描述或事件,用相同的 URL 重新创建它即可。不重试
not_found404No operation exists at this path.

/api/v1 下的路径不对应任何操作:拼写错误、缺少或多出路径段。

任何操作都可能返回此错误码。

对照 API 参考检查路径;所有操作都位于 /api/v1 之下。不重试
webhook_not_found随 API 密钥推出404The API key's account has no webhook endpoint with this id.

端点 ID 不属于该密钥所在的账号:已被删除、输入有误,或者属于其他账号。

操作: Delete a webhook endpoint, Send a test event

用 GET /api/v1/webhooks 列出账号的端点,并使用其中的 ID。不重试
method_not_allowed405The path exists but does not accept this HTTP method; see the Allow header.

用 GET 调用 POST 操作——例如在浏览器地址栏中打开它——或者反过来。

任何操作都可能返回此错误码。

使用 Allow 响应头中列出的方法:接收 JSON 请求体的操作用 POST,其他操作用 GET。不重试
payload_too_large413The body exceeds 100 KB.

请求体超过 100 KB,通常是因为把整个证书包或文件粘贴进了一个字段。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

每次调用少发送一些数据——一条证书链、一个令牌。不重试
rate_limited429Too many requests — see Retry-After.

当前时间窗口内请求过多:不带密钥时按 IP 计算,带密钥时按密钥计算。对域名的实际扫描还会消耗按主机计算和全局计算的额度。

操作: API self-description, Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

等待 Retry-After 中给出的秒数后再重试,并在客户端缓存响应。最多重试 2 次
quota_exceeded随 API 密钥推出429A daily or monthly quota of the API key's account is used up. X-Quota-Reset (and Retry-After) say when it starts over; retrying earlier cannot succeed.

使用密钥的调用已用完账号的每日或每月配额单位,或者每日域名扫描次数;测试密钥有各自更小的配额。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

在 X-Quota-Reset 给出的时间之前不要重试:配额要到那时才会重置,不会更早。不重试
internal_error500Unexpected server error.

API 未预料到的故障。它会连同请求 ID 一起记录到日志中——但绝不会记录请求体。

任何操作都可能返回此错误码。

如果问题持续出现,请报告错误响应体中的 requestId。不重试
scan_unreachable502The domain refused or dropped the connection on port 443.

名称可以解析,但从互联网无法成功建立到 443 端口的 TCP 连接:没有 HTTPS 服务器、防火墙拒绝或丢弃了连接,或者主机已宕机。

操作: TLS signature-health grade for a domain

确认该主机在 443 端口上向公网提供 HTTPS 服务。最多重试 2 次
scan_tls_error502The TLS handshake failed or presented no usable certificate.

443 端口的连接可以建立,但 TLS 握手以告警或协议不匹配告终,或者服务器没有发送扫描器能读取的证书。

操作: TLS signature-health grade for a domain

检查服务器的 TLS 配置,例如查看域名健康报告。最多重试 2 次
service_unavailable随 API 密钥推出503API keys cannot be verified right now (the key store is unreachable); retry shortly.

无法访问密钥存储,因此无法验证请求中提供的密钥。携带密钥的调用绝不会被当作匿名调用处理。

操作: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

稍后重试——SDK 会自动这样做。最多重试 2 次
webhooks_unavailable随 API 密钥推出503Webhooks are switched off on this server: it has no signing keys configured.

服务器没有配置 Webhook 签名密钥,因此无法对投递签名;在配置密钥之前,所有 Webhook 操作都会返回此错误码。

操作: List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

请求本身无需修改:此服务器暂时关闭了 Webhook。请稍后再试。最多重试 2 次
scan_timeout504The scan did not finish in time.

解析名称、建立连接或 TLS 握手的耗时超出了扫描器允许的时间——主机响应慢或负载过高,或者数据包被静默丢弃。

操作: TLS signature-health grade for a domain

稍后重试;响应慢或负载过高的主机可能会超出时限。最多重试 2 次
timeout504The operation did not finish within its time budget.

处理请求的时间超过了 10 秒的时限。在请求限制范围内的输入预计不会出现这种情况。

操作: API self-description, Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event

重试一次;如果相同的输入再次超时,请报告错误响应体中的 requestId。最多重试 2 次

重试

官方 SDK 会重试 429(quota_exceeded 除外)、502、503 和 504——最多 2 次——等待时间以 Retry-After 的要求为准(最长 60 秒),没有该响应头时采用带完全抖动(full jitter)的指数退避。每个操作都是其输入的纯函数,因此重试总是安全的;你自己的客户端也可以遵循同样的规则。