JuliusBrussee/caveman · error
kms: %s request failed: %w
Error message
kms: %s request failed: %w
What it means
Inside the low-level call helper: the POST to {apiBaseURL}/key-manager/v1alpha1/regions/{region}/keys/{keyID}/{operation} failed at the transport level (httpClient.Do returned an error). The %w wraps Go net/http errors — DNS failure, connection refused, TLS handshake problems, timeouts, or context cancellation. This is distinct from 1198, which fires when the request completes but the status is not 200.
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 27d5a3981a)
Solutions
- Read the wrapped net/http error — 'connection refused'/'no such host' point at network, 'context deadline exceeded' at your timeout
- Verify egress to the key-manager API endpoint is allowed (firewall, NetworkPolicy, proxy)
- If behind a TLS-inspecting proxy, add its CA to the client's trust store or configure the http.Client accordingly
- Increase or remove an overly tight context deadline on the KMS call path
Example fix
// before ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) deferred := cancel _ = client.Encrypt(ctx, plaintext) // after ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() _ = client.Encrypt(ctx, plaintext)
Defensive patterns
Strategy: retry
Validate before calling
func canReachKMS(ctx context.Context, endpoint string) bool {
req, _ := http.NewRequestWithContext(ctx, http.MethodHead, endpoint, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil { return false }
resp.Body.Close()
return true
} Try / catch
var pt []byte
err := backoffRetry(func() error {
var e error
pt, e = client.Encrypt(ctx, plaintext)
return e
}) // retry only on transport errors (kms: ... request failed) Prevention
- Give KMS calls their own context with a sane (multi-second) deadline
- Pre-flight DNS/egress checks for the KMS endpoint in deployment smoke tests
- Trust the system CA store or explicitly configure proxies for MITM environments
When it happens
Trigger: DNS for the Scaleway API not resolvable from the container; connection refused by an egress firewall; TLS certificate validation failing behind a MITM proxy; context cancelled/deadline exceeded because the caller's ctx timed out; proxy misconfiguration in HTTP_PROXY env vars.
Common situations: Kubernetes cluster without egress rules allowing the KMS endpoint; corporate MITM proxy whose CA is not in the trust store; short client-side context deadlines; local dev on VPN with split DNS not resolving internal/API names.
Related errors
- Claude usage request failed with HTTP %d
- kms: %s returned HTTP %d
- kms: read %s response: %w
- registration failed: HTTP ${response.status}
- binary download failed: HTTP ${response.status}
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/124e113746692538.
Report an issue: GitHub.