Error accessing endpoint on port 8443

I need to access an external service running on port 8443. The request works in Postman, but when I make that same request through VTEX via a middleware, it returns an error (from what I understood, VTEX only accepts requests on ports 80 and 443 by default). I’ve already opened a ticket with VTEX and after several suggestions the code ended up like this (attached below), but it still doesn’t work. I tried declaring the port directly in the URL and in the header, only in the URL, only in the header, but nothing worked. Has anyone been through something similar and managed to solve it?

import { ExternalClient, InstanceOptions, IOContext } from 'vtex/api';
import axios, { AxiosResponse } from 'axios';

interface GetDiscountInfoProps {
  cnpj: string | string[];
}
export default class VTEXApi extends ExternalClient {
  private url: string;
  private apiToken: string;

  constructor(context: IOContext, options?: InstanceOptions) {
    super('', context, options);
    this.url = https://exemplo.com.br:8443/rest/api/integration/...
    this.apiToken = 'token';
  }

  public async checkCnpj(params: GetDiscountInfoProps): Promise<any | null> {

    const {cnpj} = params
    try {
      const response: AxiosResponse<any> = await axios.post(
        this.url,
        { cnpj },
        {
          headers: {
            'X-WS-TOKEN-AUTH': this.apiToken,
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'X-VTEX-Use-Https': true,
            'X-VTEX-Remote-Port': 8443
          },
        }
      );
      return response.data;
    } catch (error) {
      console.error('Error verifying CNPJ', error );
      return null;
    }
  }
}

I tested several variations of this code and got some error responses, for example the error below

Error verifying CNPJ AxiosError: connect ECONNREFUSED 186.248.229.xxx:8443
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16) {
  port: 8443,
  address: '186.248.229.xxx',
  syscall: 'connect',
  code: 'ECONNREFUSED',
  errno: -111,
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function] },
    validateStatus: [Function: validateStatus],

Hey buddy, how’s it going?

Have you already added this route with port 8843 to the service’s policy list?

Ex:

    {
      "name": "outbound-access",
      "attrs": {
        "host": "exemplo.com.br:8443",
        "path": "*"
      }
    },

Good afternoon, @Nikolavno.

Yes, I’ve already declared that route, I tested it in several ways

 {
      "name": "outbound-access",
      "attrs": {
        "host": "exemplo.com.br:8443",
        "path": "*"
      }
    },
}

 {
      "name": "outbound-access",
      "attrs": {
        "host": "exemplo.com.br",
        "path": "*",
        "port": "8443"
      }
    },
}

 {
      "name": "outbound-access",
      "attrs": {
        "host": "exemplo.com.br:8443",
        "path": "*"
        "port": "8443"
      }
    },
}

 {
      "name": "outbound-access",
      "attrs": {
        "host": "exemplo.com.br",
        "path": "*"
      }
    },
}

None of those made it work, but I kept it in the format you mentioned

The latest error I’m getting is the one below:

Client network socket disconnected before secure TLS connection was established
    at connResetException (node:internal/errors:705:14)
    at TLSSocket.onConnectEnd (node:_tls_wrap:1594:19)
    at TLSSocket.emit (node:events:525:35)
    at endReadableNT (node:internal/streams/readable:1358:12)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  localAddress: undefined,
  port: 443,
  host: 'exemplo.com.br',
  path: null,
  code: 'ECONNRESET',
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function] },
    validateStatus: [Function: validateStatus]

I understand, in this case you’re also correctly using the VTEX-Use-Https header.

This error is usually the default error when VTEX is not authorizing your service to communicate with that external route for security reasons.

Since this can only be resolved by VTEX support, I’d suggest following up on the ticket.

Now, as a workaround, what I would do is:

1 - Create an external API/middleware that will handle the communication between the API and the Service
2 - Call this API from the VTEX Service, and that API then calls the external API on the specific port.

I know it might sound a bit more work, but I guarantee it will work.