caddyserver/caddy · error

failed getting EAB credentials: HTTP %d

Error message

failed getting EAB credentials: HTTP %d

What it means

The EAB credentials request completed and the body decoded without a structured error code, but the HTTP status was not 200 (e.g. 429, 500, 503). This branch is reached only after the ZeroSSL-specific error.code check passed, so it represents non-200 statuses with otherwise clean payloads — generally server-side or rate-limit conditions.

Source

Thrown at modules/caddytls/acmeissuer.go:410

		Success bool `json:"success"`
		Error   struct {
			Code int    `json:"code"`
			Type string `json:"type"`
		} `json:"error"`
		EABKID     string `json:"eab_kid"`
		EABHMACKey string `json:"eab_hmac_key"`
	}
	err = json.NewDecoder(resp.Body).Decode(&result)
	if err != nil {
		return nil, acct, fmt.Errorf("decoding API response: %v", err)
	}
	if result.Error.Code != 0 {
		// do this check first because ZeroSSL's API returns 200 on errors
		return nil, acct, fmt.Errorf("failed getting EAB credentials: HTTP %d: %s (code %d)",
			resp.StatusCode, result.Error.Type, result.Error.Code)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, acct, fmt.Errorf("failed getting EAB credentials: HTTP %d", resp.StatusCode)
	}

	if c := iss.logger.Check(zapcore.InfoLevel, "generated EAB credentials"); c != nil {
		c.Write(zap.String("key_id", result.EABKID))
	}

	return &acme.EAB{
		KeyID:  result.EABKID,
		MACKey: result.EABHMACKey,
	}, acct, nil
}

// UnmarshalCaddyfile deserializes Caddyfile tokens into iss.
//
//	... acme [<directory_url>] {
//	    dir <directory_url>
//	    test_dir <test_directory_url>
//	    email <email>

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Wait and retry: reload Caddy or trigger re-issuance after a few minutes; 429/5xx are usually transient.
  2. Reduce issuance burstiness by staggering new hostnames or pre-generating EAB credentials.
  3. Check ZeroSSL status/announcements for ongoing incidents.
  4. As a durable fallback, configure manual external_account credentials or use Let's Encrypt as the issuer.
Defensive patterns

Strategy: retry

Try / catch

if err := registerZeroSSL(ctx); err != nil {
    msg := err.Error()
    if strings.Contains(msg, "failed getting EAB credentials: HTTP 4") || strings.Contains(msg, "HTTP 5") {
        // rate limit / server error: back off and retry later
        scheduleRetry(15 * time.Minute)
    }
}

Prevention

When it happens

Trigger: ZeroSSL returning 429 (rate limit) or 5xx during API incidents; gateway timeouts from ZeroSSL's infrastructure; any non-200 response whose JSON has error.code == 0.

Common situations: Bursty certificate issuance (many new domains at once) tripping ZeroSSL rate limits; ZeroSSL outages; retry storms after config reloads.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/b5694a8b79f32d79. Report an issue: GitHub.