{"record":{"id":"85b9ea149ca2b628","repo":"bytebase/bytebase","slug":"failed-to-connect-to-opensearch","errorCode":null,"errorMessage":"failed to connect to OpenSearch","messagePattern":"failed to connect to OpenSearch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/plugin/db/elasticsearch/elasticsearch.go","lineNumber":349,"sourceCode":"\t\tctx := context.Background()\n\t\tinfo, err := d.opensearchAPI.Info(ctx, &opensearchapi.InfoReq{})\n\t\tif err != nil {\n\t\t\t// Check if it's an authentication or connection issue\n\t\t\terrStr := err.Error()\n\t\t\tif strings.Contains(errStr, \"401\") || strings.Contains(errStr, \"403\") {\n\t\t\t\t// Check if role assumption was attempted\n\t\t\t\tif d.config.DataSource.GetAwsCredential() != nil &&\n\t\t\t\t\td.config.DataSource.GetAwsCredential().RoleArn != \"\" {\n\t\t\t\t\treturn errors.Errorf(\"authentication failed: unable to assume role %s: %v\",\n\t\t\t\t\t\td.config.DataSource.GetAwsCredential().RoleArn, err)\n\t\t\t\t}\n\t\t\t\treturn errors.Errorf(\"authentication failed (consider using cross-account role if accessing different AWS account): %v\", err)\n\t\t\t}\n\t\t\tif strings.Contains(errStr, \"404\") {\n\t\t\t\treturn errors.Errorf(\"endpoint not found (check if path is correct): %v\", err)\n\t\t\t}\n\t\t\t// For any other error, return the full error\n\t\t\treturn errors.Wrapf(err, \"failed to connect to OpenSearch\")\n\t\t}\n\t\tif info == nil || info.Version.Number == \"\" {\n\t\t\treturn errors.New(\"invalid response from server\")\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Use Elasticsearch client\n\tif d.typedClient != nil {\n\t\tres, err := d.typedClient.Ping()\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"failed to ping db\")\n\t\t}\n\t\tdefer res.Body.Close()\n\t\tif res.IsError() {\n\t\t\treturn errors.Errorf(\"ping failed: %s\", res.String())\n\t\t}\n\t\treturn nil","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/db/elasticsearch/elasticsearch.go#L331-L367","documentation":"This is the fallback wrap applied in Ping when the Info request fails with any error that is neither 401/403 nor 404 — i.e. the driver could not obtain cluster info for an unclassified reason. The original error is preserved as the cause; the message names the OpenSearch connection attempt.","triggerScenarios":"Ping() -> opensearchAPI.Info() returns an error whose string does not contain \"401\", \"403\", or \"404\": network timeouts, DNS failures, connection refused, TLS handshake errors, 5xx responses, or malformed responses from the server.","commonSituations":"Domain is not reachable from the network/VPC (security group blocks the port); DNS typo in host; expired TLS certificate causing handshake failure; server returning 502/503 from a proxy; request timeout due to a cold/serverless domain.","solutions":["Read the wrapped cause to identify whether it is DNS, connection refused, TLS, or an HTTP 5xx error.","Verify network reachability: same VPC/security group rules allow traffic to the domain's port from the Bytebase host.","Confirm the TLS certificate is valid (or configured CA) and the scheme matches the listener.","If a proxy returns 5xx, check the upstream domain health in the AWS/OpenSearch console."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const reachable = await fetch(dataSource.address + \"/\", { signal: AbortSignal.timeout(5000) }).then(r => r.ok).catch(() => false);\nif (!reachable) throw new Error(\"OpenSearch endpoint unreachable from this host\");","typeGuard":null,"tryCatchPattern":"try {\n  await driver.ping(ctx);\n} catch (e) {\n  if (String(e).includes(\"failed to connect to OpenSearch\")) {\n    // inspect e.cause for DNS/TLS/timeout and retry with backoff for transient 5xx\n  }\n  throw e;\n}","preventionTips":["Pre-check network reachability (VPC, security groups, DNS) before configuring the instance","Keep TLS certificates valid and trusted by the host","Add retry with backoff for cold start / transient 5xx responses"],"tags":["elasticsearch","opensearch","network","connectivity"],"backgroundTag":"http-request-failed","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}