caddyserver/caddy · error

performing EAB credentials request: %v

Error message

performing EAB credentials request: %v

What it means

The HTTP POST to ZeroSSL's EAB credentials endpoint (https://app.zerossl.com/acme/eab-credentials-email) failed at the transport level. This is a network-level failure: DNS resolution, TCP connection, TLS handshake, timeout, or connection refused. Note it uses http.DefaultClient, so it does not honor the issuer's configured proxy or timeouts.

Source

Thrown at modules/caddytls/acmeissuer.go:387

	if len(acct.Contact) == 0 {
		// we borrow the email from config or the default email, so ensure it's saved with the account
		acct.Contact = []string{"mailto:" + iss.Email}
	}

	endpoint := zerossl.BaseURL + "/acme/eab-credentials-email"
	form := url.Values{"email": []string{iss.Email}}
	body := strings.NewReader(form.Encode())

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, body)
	if err != nil {
		return nil, acct, fmt.Errorf("forming request: %v", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("User-Agent", certmagic.UserAgent)

	resp, err := http.DefaultClient.Do(req) //nolint:gosec // no SSRF since URL is from trusted config
	if err != nil {
		return nil, acct, fmt.Errorf("performing EAB credentials request: %v", err)
	}
	defer resp.Body.Close()

	var result struct {
		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

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Verify outbound connectivity: curl -fsSL https://app.zerossl.com/ from the Caddy host.
  2. Check DNS and firewall rules for app.zerossl.com on port 443, then retry issuance (systemctl reload caddy or a config change triggers a retry).
  3. If egress is permanently restricted, obtain EAB credentials out-of-band from the ZeroSSL dashboard and configure external_account eab_kid/eab_hmac_key instead of relying on automatic generation.
  4. If the problem persists, check ZeroSSL status pages or switch the issuer to Let's Encrypt.

Example fix

// before: relying on automatic EAB generation behind a restricted firewall
{"issuer": {"ca": "https://zerossl.com/acme/eab"}}

// after: out-of-band EAB credentials
{
  "issuer": {
    "ca": "https://zerossl.com/acme/eab",
    "external_account": {
      "key_id": "<from ZeroSSL dashboard>",
      "mac_key": "<from ZeroSSL dashboard>"
    }
  }
}
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight connectivity to the EAB endpoint before enabling ZeroSSL.
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Head("https://app.zerossl.com/")
if err != nil {
    return fmt.Errorf("no egress to ZeroSSL API: %v; configure manual EAB credentials", err)
}

Try / catch

var lastErr error
for attempt := 0; attempt < 3; attempt++ {
    lastErr = registerZeroSSL(ctx)
    if lastErr == nil || !strings.Contains(lastErr.Error(), "performing EAB credentials request") {
        break
    }
    time.Sleep(time.Duration(attempt+1) * 5 * time.Second)
}

Prevention

When it happens

Trigger: Any of: no internet egress from the Caddy host, DNS failure resolving app.zerossl.com, a firewall blocking outbound HTTPS, ZeroSSL being unreachable, or the process context being cancelled mid-request.

Common situations: Servers in isolated networks attempting ZeroSSL issuance; transient ZeroSSL outages; strict outbound firewall rules that only allow the ACME directory host but not the API host; IPv6-only hosts with broken routing.

Related errors


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