JuliusBrussee/caveman · error
kms: request failed
Error message
kms: %s request failed: %w
What it means
This error wraps a transport-level failure from the KMS client's HTTP request in kms.go. The client builds an authenticated request (content-type, accept, x-auth-token headers) and performs it via c.httpClient.Do; if the request never completes (connection failure, DNS, timeout, TLS), it returns this wrapped error with the operation name (Encrypt or Decrypt). It indicates the KMS endpoint was not reached at all, not that the server rejected the request.
Solutions
- Verify the KMS endpoint URL/host and port in configuration and that the KMS service is reachable (curl the health endpoint).
- Check network connectivity: DNS resolution, firewall/security-group rules, and proxy environment variables.
- Inspect the wrapped error with errors.Unwrap or %v to see the underlying cause (connection refused, timeout, x509 error).
- If the cause is a timeout or stale connection, retry with backoff or tune the httpClient's Timeout/Transport settings.
- If TLS-related, confirm the CA bundle/trusted roots available to the process.
Example fix
// before
out, err := kms.Encrypt(ctx, plaintext) // fails: kms: Encrypt request failed: dial tcp 10.0.0.5:8200: connect: connection refused
// after
if err != nil {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
// retry with backoff
} else {
log.Fatalf("KMS unreachable, check endpoint %q: %v", cfg.KMSEndpoint, err)
}
} Defensive patterns
Strategy: retry
Validate before calling
// before calling Encrypt/Decrypt
u, err := url.Parse(cfg.KMSEndpoint)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid KMS endpoint %q", cfg.KMSEndpoint)
}
conn, err := net.DialTimeout("tcp", u.Host, 2*time.Second)
if err != nil {
return fmt.Errorf("KMS unreachable at %s: %w", u.Host, err)
}
conn.Close() Try / catch
if err != nil {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
// retry with backoff
}
return fmt.Errorf("kms transport: %w", err)
} Prevention
- Health-check the KMS endpoint at startup and before critical operations.
- Use exported constants and a single config source for the endpoint URL.
- Set explicit, sane httpClient timeouts and disable stale keep-alive reuse.
- Monitor connectivity from the deployment environment (firewalls, proxies, DNS).
When it happens
Trigger: Calling Encrypt or Decrypt when the KMS server is unreachable: wrong host/port in the KMS endpoint config, server down, DNS failure, TLS handshake failure, network partition, or an http.Client timeout/expired connection being reused.
Common situations: Deploying with a stale or mistyped KMS URL, the KMS service container not running (connection refused), firewalls blocking egress, using https:// against a plaintext server or vice versa, or a proxy misconfiguration in the environment.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- kms: read response
- kms: create request
- kms: returned HTTP
- secretbox: KMS encrypt
- secretbox: payload KMS encrypt
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/124e113746692538.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/kms/kms.go:362
}
func (c *Client) call(ctx context.Context, region, keyID, operation string, input, output any) error {
body, err := json.Marshal(input)
if err != nil {
return fmt.Errorf("kms: encode %s request: %w", operation, err)
}
endpoint := c.apiBaseURL + "/key-manager/v1alpha1/regions/" + url.PathEscape(region) +
"/keys/" + url.PathEscape(keyID) + "/" + operation
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))
if err != nil {
return fmt.Errorf("kms: create %s request: %w", operation, err)
}
req.Header.Set("content-type", "application/json")
req.Header.Set("accept", "application/json")
req.Header.Set("x-auth-token", c.token)
resp, err := c.httpClient.Do(req)
if err != nil {
return fmt.Errorf("kms: %s request failed: %w", operation, err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
_, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 32<<10))
return fmt.Errorf("kms: %s returned HTTP %d", operation, resp.StatusCode)
}
data, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseBytes+1))
if err != nil {
return fmt.Errorf("kms: read %s response: %w", operation, err)
}
if len(data) > maxResponseBytes {
return fmt.Errorf("kms: %s response exceeds limit", operation)
}
if err := json.Unmarshal(data, output); err != nil {
return fmt.Errorf("kms: decode %s response: %w", operation, err)
}
return nil
}View on GitHub (pinned to 3ee70a1026)