{"record":{"id":"124e113746692538","repo":"JuliusBrussee/caveman","slug":"kms-s-request-failed-w","errorCode":null,"errorMessage":"kms: %s request failed: %w","messagePattern":"kms: (.+?) request failed: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/kms/kms.go","lineNumber":362,"sourceCode":"}\n\nfunc (c *Client) call(ctx context.Context, region, keyID, operation string, input, output any) error {\n\tbody, err := json.Marshal(input)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kms: encode %s request: %w\", operation, err)\n\t}\n\tendpoint := c.apiBaseURL + \"/key-manager/v1alpha1/regions/\" + url.PathEscape(region) +\n\t\t\"/keys/\" + url.PathEscape(keyID) + \"/\" + operation\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kms: create %s request: %w\", operation, err)\n\t}\n\treq.Header.Set(\"content-type\", \"application/json\")\n\treq.Header.Set(\"accept\", \"application/json\")\n\treq.Header.Set(\"x-auth-token\", c.token)\n\tresp, err := c.httpClient.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kms: %s request failed: %w\", operation, err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\t_, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 32<<10))\n\t\treturn fmt.Errorf(\"kms: %s returned HTTP %d\", operation, resp.StatusCode)\n\t}\n\tdata, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseBytes+1))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kms: read %s response: %w\", operation, err)\n\t}\n\tif len(data) > maxResponseBytes {\n\t\treturn fmt.Errorf(\"kms: %s response exceeds limit\", operation)\n\t}\n\tif err := json.Unmarshal(data, output); err != nil {\n\t\treturn fmt.Errorf(\"kms: decode %s response: %w\", operation, err)\n\t}\n\treturn nil\n}","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/kms/kms.go#L344-L380","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nout, err := kms.Encrypt(ctx, plaintext) // fails: kms: Encrypt request failed: dial tcp 10.0.0.5:8200: connect: connection refused\n// after\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // retry with backoff\n    } else {\n        log.Fatalf(\"KMS unreachable, check endpoint %q: %v\", cfg.KMSEndpoint, err)\n    }\n}","handlingStrategy":"retry","validationCode":"// before calling Encrypt/Decrypt\nu, err := url.Parse(cfg.KMSEndpoint)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid KMS endpoint %q\", cfg.KMSEndpoint)\n}\nconn, err := net.DialTimeout(\"tcp\", u.Host, 2*time.Second)\nif err != nil {\n    return fmt.Errorf(\"KMS unreachable at %s: %w\", u.Host, err)\n}\nconn.Close()","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // retry with backoff\n    }\n    return fmt.Errorf(\"kms transport: %w\", err)\n}","preventionTips":["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)."],"tags":["network","http","kms","go"],"backgroundTag":"http-request-failed","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}