<p>I have an Elasticsearch DB running on Kubernetes exposed to <code>my_domain.com/elastic</code> as an Istio virtual service, which I have no problem accessing via the browser (as in I get to login successfully to the endpoint). I can also query the DB with Python's Requests. But I can't access the DB with the official python client if I use <code>my_domain.com/elastic</code>. The LoadBalancer IP works perfectly well even with the client. What am I missing? I have SSL certificates set up for my_domain.com via Cert-Manager and CloudFlare.</p>
<p>This works:</p>
<pre><code>import requests
import os
data = ' { &quot;query&quot;: { &quot;match_all&quot;: {} } }'
headers = {'Content-Type': 'application/json'}
auth= ('elastic', os.environ['ELASTIC_PASSWORD']) 
response = requests.post('https://mydomain.cloud/elastic/_search', auth=auth,  data=data, headers=headers)
print(response.text)
</code></pre>
<p>This doesn't work (I have tried a number of different parameters):</p>
<pre><code>from datetime import datetime
import os
from elasticsearch import Elasticsearch, RequestsHttpConnection


es = Elasticsearch(,
   [{'host': 'mydomain.cloud', 'port': 443, 'url_prefix': 'elastic', 'use_ssl': True}],
    http_auth=('elastic', os.environ['ELASTIC_PASSWORD']), # 1Password or kubectl get secret elastic-cluster-es-elastic-user -o go-template='{{.data.elastic | base64decode}}' -n elastic-system
    schema='https'#, verify_certs=False,
    # use_ssl=True,
    # connection_class = RequestsHttpConnection,
    # port=443,
)

# if not es.ping():
#     raise ValueError(&quot;Connection failed&quot;)

doc = {
    'author': 'kimchy',
    'text': 'Elasticsearch: cool. bonsai cool.',
    'timestamp': datetime.now(),
}
res = es.index(index=&quot;test-index&quot;, id=1, document=doc)
print(res['result'])

res = es.get(index=&quot;test-index&quot;, id=1)
print(res['_source'])

es.indices.refresh(index=&quot;test-index&quot;)

res = es.search(index=&quot;test-index&quot;, query={&quot;match_all&quot;: {}})
print(&quot;Got %d Hits:&quot; % res['hits']['total']['value'])
for hit in res['hits']['hits']:
    print(&quot;%(timestamp)s %(author)s: %(text)s&quot; % hit[&quot;_source&quot;])
</code></pre>
<p>The resulting error:</p>
<pre><code>elasticsearch.exceptions.RequestError: RequestError(400, 'no handler found for uri [//test-index/_doc/1] and method [PUT]', 'no handler found for uri [//test-index/_doc/1] and method [PUT]') 
</code></pre>
<p>cluster.yaml</p>
<pre><code>apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: elastic-cluster
  namespace: elastic-system
spec:
  version: 7.15.2
  http:
    # tls:
    #   selfSignedCertificate:
    #      disabled: true
    service:
      spec:
        type: LoadBalancer
  nodeSets:
  - name: master-nodes
    count: 2
    config:
      node.roles: [&quot;master&quot;]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data # Do not change this name unless you set up a volume mount for the data path.
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 5Gi
        storageClassName: local-storage
  - name: data-nodes
    count: 2
    config:
      node.roles: [&quot;data&quot;]
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data # Do not change this name unless you set up a volume mount for the data path.
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 10Gi
        storageClassName: local-storage
    podTemplate:
      # metadata:
      #   annotations:
      #     traffic.sidecar.istio.io/includeInboundPorts: &quot;*&quot;
      #     traffic.sidecar.istio.io/excludeOutboundPorts: &quot;9300&quot; 
      #     traffic.sidecar.istio.io/excludeInboundPorts: &quot;9300&quot;
      spec:
        # automountServiceAccountToken: true
        containers:
        - name: elasticsearch
          resources:
            requests:
              memory: 4Gi
              cpu: 3
            limits:
              memory: 4Gi
              cpu: 3
</code></pre>
<p>virtual-service.yaml</p>
<pre><code>apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: elastic-vts
  namespace: elastic-system
spec:
  hosts:
  - &quot;mydomain.cloud&quot;
  gateways:
  - istio-system/gateway
  http:
  - match:
    - port: 443
    - uri:
        prefix: /elastic
    rewrite:
      uri: /
    route:
    - destination:
        host: elastic-cluster-es-http.elastic-system.svc.cluster.local
        port:
          number: 9200
</code></pre>
<p>destination-rule.yaml</p>
<pre><code>apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: elastic-destination-rule
  namespace: elastic-system
spec:
  host: elastic-cluster-es-http.elastic-system.svc.cluster.local
  trafficPolicy:
    tls:
      mode: SIMPLE
</code></pre>
<p>gateway.yaml</p>
<pre><code>apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - 'mydomain.cloud'
    tls:
      httpsRedirect: true
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
      - 'mydomain.cloud'
    tls:
      mode: SIMPLE
      credentialName: letsencrypt-staging-tls
     
</code></pre>

<p>I have reproduced your problem and the solution is as follows. First, pay attention to your yaml file:</p>
<pre><code>apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: elastic-vts
  namespace: elastic-system
spec:
  hosts:
  - &quot;mydomain.cloud&quot;
  gateways:
  - istio-system/gateway
  http:
  - match:
    - port: 443
    - uri:
        prefix: /elastic   &lt;---- here is the problem
    rewrite:
      uri: /
      ...
</code></pre>
<p>The error that appears looks like this:</p>
<pre><code>elasticsearch.exceptions.RequestError: RequestError(400, 'no handler found for uri [//test-index/_doc/1] and method [PUT]', 'no handler found for uri [//test-index/_doc/1] and method [PUT]')
</code></pre>
<p>The problem is right there: <code>[//test-index/_doc/1]</code> (it's about a duplicate / character). I think it's a similar problem to the problem mentioned <a href="https://github.com/elastic/elasticsearch-js/issues/572" rel="nofollow noreferrer">here</a>. To fix this, I suggest adding the <code>/</code> to the line <code>prefix: /elastic</code> and your yaml will be like this example:</p>
<pre><code>apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: elastic-vts
  namespace: elastic-system
spec:
  hosts:
  - &quot;mydomain.cloud&quot;
  gateways:
  - istio-system/gateway
  http:
  - match:
    - port: 443
    - uri:
        prefix: /elastic/ &lt;---- here
    rewrite:
      uri: /
      ...
</code></pre>
<p>In this moment the answer from Elastic looks like:</p>
<pre><code>Got 1 Hits:
2021-12-30T09:20:12.038004 kimchy: Elasticsearch: cool. bonsai cool.
</code></pre>
