Resolvendo o ORA-17820: conectando ao RAC através de NAT

Recentemente, um fornecedor externo estava com problemas de conexão a um Oracle RAC, onde as tentativas de conexão ao banco retornavam o erro ORA-17820: The network adapter could not establish the connection. Aqui vou explicar como funciona a conexão de uma aplicação com um banco no Oracle RAC, porque esse erro ocorre e como resolvê-lo.

Como funciona a conexão no Oracle RAC?

No Oracle RAC, a conexão ao banco é feita através do SCAN (Single Client Access Name). Esse SCAN consistem em três VIPs (virtual IPs), que são distribuídos entre os nós do RAC, e um SCAN listener para cada um dos VIPs. Se o SCAN é resolvido por um DNS, esse DNS retorna os três VIPs do SCAN para o client.

A conexão funciona da seguinte forma:

  1. O client usa um dos VIPs retornados pelo DNS do SCAN, para fazer a solicitação de conexão ao SCAN;
  2. Quando o SCAN recebe a requisição, ele responde ao client com um pacote de redirecionamento TNS, que contém as informações de endereço (IP ou FQDN e porta) do local listener do nó com menor carga;
  3. O client então solicita a conexão ao listener local usando a informação recebida do SCAN, para fechar a conexão com o banco de dados;

O SCAN recebe as informações sobre os listeners locais através do processo PMON de cada instância do RAC. O PMON pega a informação configurada no parâmetro LOCAL_LISTENER da instância, e envia essa informação para os listeners configurados no parâmetro REMOTE_LISTENER (o SCAN é configurado neste parâmetro), pois são esses listeners remotos que fazem o redirecionamento para os listeners locais.

Como identificar o que está sendo enviado pelo SCAN?

Uma forma de ver esse processo acontecendo pode ser feita habilitando o trace de conexões no client. Para isso, basta adicionar ao sqlnet.ora do client os seguintes parâmetros:

DIAG_ADR_ENABLED = OFF
TRACE_LEVEL_CLIENT = SUPPORT
TRACE_DIRECTORY_CLIENT = /home/oracle/trace # aqui pode ser qualquer diretório com permissão de leitura e escrita
TRACE_TIMESTAMP_CLIENT = ON 

Agora, quando uma nova tentativa de conexão for feita, serão criados arquivos de trace para cada tentativa de conexão, e os traces serão armazenados no diretório indicado no parâmetro TRACE_DIRECTORY_CLIENT. Dentro desses trace files são feitos os dumps dos pacotes enviados e recebidos pelo client. Portanto, podemos ver dentro desse trace o pacote de redirecionamento, semelhante ao trecho abaixo:

(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: packet dump
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 01 30 00 00 06 00 00 00  |.0......|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 00 40 28 41 44 44 52 45  |.@(ADDRE|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 53 53 3D 28 50 52 4F 54  |SS=(PROT|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 4F 43 4F 4C 3D 54 43 50  |OCOL=TCP|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 29 28 48 4F 53 54 3D 31  |)(HOST=1|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 30 2E 31 38 38 2E 39 39  |0.198.11|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 2E 31 30 31 29 28 50 4F  |.101)(PO|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 52 54 3D 31 35 32 31 29  |RT=1521)|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 29 00 28 44 45 53 43 52  |).(DESCR|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 49 50 54 49 4F 4E 3D 28  |IPTION=(|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 41 44 44 52 45 53 53 3D  |ADDRESS=|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 28 50 52 4F 54 4F 43 4F  |(PROTOCO|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 4C 3D 54 43 50 29 28 48  |L=TCP)(H|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 4F 53 54 3D 31 30 2E 31  |OST=10.1|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 38 38 2E 39 39 2E 39 39  |98.11.99|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 29 28 50 4F 52 54 3D 31  |)(PORT=1|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 35 32 31 29 28 48 4F 53  |521)(HOS|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 54 4E 41 4D 45 3D 63 64  |TNAME=se|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 6D 32 67 74 2D 73 63 61  |rver1-sc|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 6E 2E 71 61 2E 68 6F 73  |an.local|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 74 2E 70 61 67 73 29 29  |domain))|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 28 43 4F 4E 4E 45 43 54  |(CONNECT|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 5F 44 41 54 41 3D 28 53  |_DATA=(S|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 45 52 56 49 43 45 5F 4E  |ERVICE_N|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 41 4D 45 3D 43 44 4D 32  |AME=ORCL|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 47 54 29 28 43 49 44 3D  |GT)(CID=|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 28 50 52 4F 47 52 41 4D  |(PROGRAM|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 3D 73 71 6C 70 6C 75 73  |=sqlplus|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 29 28 48 4F 53 54 3D 69  |)(HOST=s|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 70 2D 31 30 2D 31 38 38  |erver1)(|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 55 53 45 52 3D 6F 72 61  |USER=ora|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 63 6C 65 29 29 28 53 45  |cle))(SE|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 52 56 45 52 3D 64 65 64  |RVER=ded|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 69 63 61 74 65 64 29 28  |icated)(|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 49 4E 53 54 41 4E 43 45  |INSTANCE|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 5F 4E 41 4D 45 3D 63 64  |_NAME=or|
(2504985088) [16-OCT-2025 16:32:24:986] nsprecv: 6D 32 67 74 31 29 29 29  |cl1)))  |

No início do dump, podemos notar o apontamento ao IP 10.198.11.101, que é o VIP do meu nó 1, e está configurado no LOCAL_LISTENER da instância 1 do meu RAC:

[orcl1.oracle@server1 ~]$ srvctl config vip -n server1
VIP exists: network number 1, hosting node server1
VIP Name: orcl-vip-1.localdomain
VIP IPv4 Address: 10.198.11.101
VIP IPv6 Address:
VIP is enabled.
VIP is individually enabled on nodes:
VIP is individually disabled on nodes:
[orcl1.oracle@server1 ~]$ sqlplus / as sysdba
SQL>
SQL> show parameter local_listener

NAME                                 TYPE        VALUE
------------------------------------ ----------- --------------------------------------------------------
local_listener                       string      (ADDRESS=(PROTOCOL=TCP)(HOST=10.198.11.101)(PORT=1521))

Vale lembrar que o parâmetro LOCAL_LISTENER, caso não seja explicitamente configurado durante a criação do database, é configurado automaticamente pelo CRS agent durante a primeira inicialização do banco de dados, apontando para o VIP do nó onde a instância iniciou e para o listener padrão configurado no OCR.

O que muda com o NAT?

Quando o client não está na mesma rede que o banco, como neste caso de fornecedores externos, a conexão pode ser feita através de um NAT e uma VPN, por exemplo.

Para este exemplo, digamos que o seguinte foi configurado:

FQDNDNS rede clientDNS rede banco
server-scan.localdomain10.0.0.17, 10.0.0.18, 10.0.0.1910.198.11.97, 10.198.11.98, 10.198.11.99
orcl-vip-1.localdomain10.0.0.2110.198.11.101
orcl-vip-2.localdomain10.0.0.2210.198.11.102

Teríamos o seguinte fluxo:

  1. O client aponta para o FQDN do SCAN, que passa pelo NAT e é convertido para os IPs do SCAN;
  2. O SCAN retorna a configuração do LOCAL_LISTENER do node com menor carga;
  3. O client usa essa informação do LOCAL_LISTENER, que deve conter um FQDN, como o orcl-vip-1.localdomain, usado nesse exemplo, para apontar para um IP configurado no NAT, para alcançar os listener locais.

Vale citar que aqui nesse fluxo eu omiti VPNs, regras de firewall e outros reapontamentos que podem existir num ambiente real, para simplificar a explicação.

Beleza, mas e quando o ORA-17820 aparece? Bom, no meu caso, o que aconteceu foi que o LOCAL_LISTENER das instâncias do RAC estavam com o valor default, que eu citei antes. Assim o SCAN retornava o VIP do node para o client, e quando ele tentava usar esse endereço na sua rede, a conexão não era possível, pois esse IP não existia lá. Além disso, não existia o NAT apontando para os VIPs dos nós do RAC.

Como resolver o problema?

A resolução aqui consistiu em realizar a criação do NAT apontando para os VIPs dos nós do RAC, e alterar o parâmetro LOCAL_LISTENER das instâncias do RAC, usando o FQDN ao invés dos VIPs:

SQL> alter system set local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=orcl-vip-1.localdomain)(PORT=1521))' scope=both sid='orcl1';

SQL> alter system set local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=orcl-vip-2.localdomain)(PORT=1521))' scope=both sid='orcl2';

Após a configuração, refazendo o teste com o trace habilitado, podemos observar o FQDN sendo repassado no pacote de redirecionamento:

(729733632) [16-OCT-2025 16:50:32:702] nsprecv: packet dump
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 01 3C 00 00 06 00 00 00  |.<......|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 00 40 28 41 44 44 52 45  |.@(ADDRE|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 53 53 3D 28 50 52 4F 54  |SS=(PROT|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 4F 43 4F 4C 3D 54 43 50  |OCOL=TCP|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 29 28 48 4F 53 54 3D 63  |)(HOST=o|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 64 6D 32 67 74 2D 76 69  |rcl-vip-|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 70 2D 31 2E 71 61 2E 68  |1.locald|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 6F 73 74 2E 70 61 67 73  |omain   |
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 29 28 50 4F 52 54 3D 31  |)(PORT=1|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 35 32 31 29 29 00 28 44  |521)).(D|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 45 53 43 52 49 50 54 49  |ESCRIPTI|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 4F 4E 3D 28 41 44 44 52  |ON=(ADDR|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 45 53 53 3D 28 50 52 4F  |ESS=(PRO|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 54 4F 43 4F 4C 3D 54 43  |TOCOL=TC|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 50 29 28 48 4F 53 54 3D  |P)(HOST=|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 31 30 2E 31 38 38 2E 39  |10.198.1|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 39 2E 39 39 29 28 50 4F  |1.99)(PO|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 52 54 3D 31 35 32 31 29  |RT=1521)|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 28 48 4F 53 54 4E 41 4D  |(HOSTNAM|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 45 3D 63 64 6D 32 67 74  |E=server|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 2D 73 63 61 6E 2E 71 61  |1-scan.l|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 2E 68 6F 73 74 2E 70 61  |ocaldoma|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 67 73 29 29 28 43 4F 4E  |in))(CON|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 4E 45 43 54 5F 44 41 54  |NECT_DAT|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 41 3D 28 53 45 52 56 49  |A=(SERVI|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 43 45 5F 4E 41 4D 45 3D  |CE_NAME=|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 43 44 4D 32 47 54 29 28  |ORCL1 )(|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 43 49 44 3D 28 50 52 4F  |CID=(PRO|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 47 52 41 4D 3D 73 71 6C  |GRAM=sql|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 70 6C 75 73 29 28 48 4F  |plus)(HO|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 53 54 3D 69 70 2D 31 30  |ST=serve|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 34 32 29 28 55 53 45 52  |r1)(USER|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 3D 6F 72 61 63 6C 65 29  |=oracle)|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 29 28 53 45 52 56 45 52  |)(SERVER|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 3D 64 65 64 69 63 61 74  |=dedicat|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 65 64 29 28 49 4E 53 54  |ed)(INST|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 41 4E 43 45 5F 4E 41 4D  |ANCE_NAM|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 45 3D 63 64 6D 32 67 74  |E=orcl1)|
(729733632) [16-OCT-2025 16:50:32:702] nsprecv: 31 29 29 29              |))      |

Além disso, no lado do client, foi necessário criar os devidos apontamentos para os FQDNs dos VIPs, para possibilitar a conexão com os listeners locais. Isso pode ser feito a nível de DNS ou no arquivo hosts do servidor de aplicação. Caso esse apontamento não seja feito, o erro ORA-17868: Unknown host specified: orcl-vip-1.localdomain é retornado.

Após essas configurações o ORA-17820 parou de acontecer e o client conectou com sucesso no banco de dados.

Conclusão

Quando não existe a necessidade de conexão de clients externos à rede onde se encontra o Oracle RAC, podemos utilizar o comportamento padrão do CRS agent no parâmetro LOCAL_LISTENER, apontando diretamente os VIPs. Porém quando o acesso ao banco requer a utilização de um NAT, se faz necessária a configuração dos FQDNs no parâmetro LOCAL_LISTENER, desta forma evitando o ORA-17820.

Caso você ainda tenha dúvidas sobre a configuração do REMOTE_LISTENER e do LOCAL_LISTENER, esse post do DBA Sobrinho pode te ajudar: Como Configurar SCAN_LISTENER e LOCAL_LISTENER no Oracle RAC.

Referência: Configuring the Oracle Database, Real Application Cluster (RAC) or Exadata when behind a Network Address Translator (NAT) (Doc ID 397393.1)

Publicar comentário