title: How to diagnose/fix envoy proxy "upstream connect error or disconnect/reset before headers. reset reason: connection failure"
body: <p>I have a service mesh envoy proxy configuration issue. The configuration is based on this example from the official envoy proxy site: <a href="https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/front_proxy" rel="noreferrer">https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/front_proxy</a>, and this ssl lesson: <a href="https://www.envoyproxy.io/learn/ssl" rel="noreferrer">https://www.envoyproxy.io/learn/ssl</a>.</p>
  
  <p>I have tried many different combinations of ports (80,443), namings, domains, nginx config etc..., nothing works.</p>
  
  <p>Here is my front-proxy:</p>
  
  <pre><code>static_resources:
    listeners:
    - address:
        socket_address:
          address: 0.0.0.0
          port_value: 80
      listener_filters:
        - name: "envoy.listener.tls_inspector"
          typed_config: {}
      filter_chains:
      - filter_chain_match:
          server_names: ["example.com", "www.example.com", "api.example.com", "test.example.com"]
        tls_context:
          common_tls_context:
            tls_certificates:
              - certificate_chain:
                  filename: "/etc/example-ai.pem"
                private_key:
                  filename: "/etc/example-ai.key"
      - filters:
        - name: envoy.http_connection_manager
          typed_config:
            "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
            stat_prefix: ingress_http
            access_log:
              - name: envoy.file_access_log
                config:
                  path: "/var/log/access.log"
            route_config:
              virtual_hosts:
              - name: services
                domains:
                - ["*.example.com","example.com"]
                routes:
                - match:
                    prefix: "/"
                  redirect:
                    path_redirect: "/"
                    https_redirect: true
            http_filters:
              - name: envoy.router
                config: {}
    - address:
        socket_address:
          address: 0.0.0.0
          port_value: 443
      listener_filters:
        - name: "envoy.listener.tls_inspector"
          typed_config: {}
      filter_chains:
      - filter_chain_match:
          server_names: ["api.example.com"]
        tls_context:
          common_tls_context:
            tls_certificates:
              - certificate_chain:
                  filename: "/etc/example-ai.pem"
                private_key:
                  filename: "/etc/example-ai.key"
        filters:
        - name: envoy.http_connection_manager
          typed_config:
            "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
            stat_prefix: ingress_http
            route_config:
              virtual_hosts:
              - name: api
                domains:
                - ["*.example.com","example.com"]
                routes:
                - match:
                    prefix: "/v1"
                  route:
                    cluster: api
            http_filters:
            - name: envoy.router
              config: {}
      - filters:
        - name: envoy.http_connection_manager
          config:
            codec_type: auto
            stat_prefix: ingress_http
            access_log:
              - name: envoy.file_access_log
                config:
                  path: "/var/log/access.log"
            route_config:
              name: local_route
              virtual_hosts:
              - name: services
                domains:
                - ["*.example.com","example.com"]
                routes:
                - match:
                    prefix: "/v1"
                  route:
                    cluster: api
                - match:
                    prefix: "/"
                  route:
                    cluster: frontend
            http_filters:
            - name: envoy.router
              config: {}
        tls_context:
          common_tls_context:
            tls_certificates:
              - certificate_chain:
                  filename: "/etc/example-ai.pem"
                private_key:
                  filename: "/etc/example-ai.key"
  
    clusters:
    - name: frontend
      connect_timeout: 1s
      type: strict_dns
      lb_policy: round_robin
      # http2_protocol_options: {}
      hosts:
      - socket_address:
          address: frontend
          port_value: 80
    - name: api
      connect_timeout: 1s
      type: strict_dns
      lb_policy: round_robin
      # http2_protocol_options: {}
      hosts:
      - socket_address:
          address: api
          port_value: 80
  admin:
    access_log_path: "/dev/null"
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8001
  </code></pre>
  
  <p>and the upstream service that is a connnection failure:</p>
  
  <pre><code>static_resources:
    listeners:
    - address:
        socket_address:
          address: 0.0.0.0
          port_value: 80
      filter_chains:
        tls_context:
          common_tls_context:
            tls_certificates:
              - certificate_chain:
                  filename: "/etc/example-ai.pem"
                private_key:
                  filename: "/etc/example-ai.key"
      - filters:
        - name: envoy.http_connection_manager
          typed_config:
            "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
            codec_type: auto
            stat_prefix: ingress_http
            access_log:
              - name: envoy.file_access_log
                config:
                  path: "/var/log/access.log"
            route_config:
              name: local_route
              virtual_hosts:
              - name: api
                domains:
                - "*"
                routes:
                - match:
                    prefix: "/v1"
                  route:
                    cluster: local_api
            http_filters:
            - name: envoy.router
              typed_config: {}
    clusters:
    - name: local_api
      connect_timeout: 0.25s
      type: strict_dns
      lb_policy: round_robin
      load_assignment:
        cluster_name: local_api
        endpoints:
        - lb_endpoints:
          - endpoint:
              address:
                socket_address:
                  address: 127.0.0.1
                  port_value: 443
  admin:
    access_log_path: "/dev/null"
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8082
  </code></pre>
  
  <p>and here is the /etc/nginx/conf.d/default.conf:</p>
  
  <pre><code>map $http_origin $cors_header {
      default "";
      "~^https?://[^/]+\.example\.ai(:[0-9]+)?$" "$http_origin";
  }
  
  server {
      listen       80;
      server_name  example.ai;
      root /usr/share/nginx/html;
      #charset koi8-r;
      access_log  /var/log/nginx/host.access.log  main;
  
      index index.html;
  
      location / {
  
  
        add_header 'Access-Control-Allow-Origin' 'api.example.ai' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Accept,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        # required to be able to read Authorization header in frontend
        #add_header 'Access-Control-Expose-Headers' 'Authorization' always;
  
  
        if ($request_method = 'OPTIONS') {
            # Tell client that this pre-flight info is valid for 20 days
          add_header 'Access-Control-Max-Age' 1728000;
          add_header 'Content-Type' 'text/plain charset=UTF-8';
          add_header 'Content-Length' 0;
          return 204;
        }
  
        # render react page refreshes
        if (!-e $request_filename){
          rewrite ^(.*)$ /index.html break;
        }
  
        try_files $uri $uri/ =404;
        error_log /var/log/nginx/error.log debug;
      }
  
      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
          root   /usr/share/nginx/html;
      }
  }
  </code></pre>
  
  <p>Any troubleshooting tips appreciated!</p>