ORA-28547 에러 완벽 해결 가이드 — 공식 원인과 11g·19c 호환 해결법

@JavaPark · May 09, 2026 · 22 min read

안녕하세요, 자바파커입니다.

"Connection to server failed, probable Oracle Net admin error" — 검색해보면 사례가 워낙 다양해서 정답이 안 보이는 그 메시지요.

오라클을 다루다 보면 한 번쯤 마주치는 ORA-28547. 솔직히 말하면, 인터넷에 떠도는 트러블슈팅 글들이 공식 원인과 일반 연결 문제를 뒤섞어 놓은 경우가 많습니다. 이 글은 Oracle 공식 문서를 기준으로 진짜 ORA-28547의 원인만 정리했습니다. 결론부터 말씀드리면 — 공식 원인은 5가지로 좁혀지고, 그 외에 자주 거론되는 항목들은 ORA-28547과 다른 에러 코드의 문제일 가능성이 높습니다.

이 글은 Oracle 11g R2부터 19c까지 동일하게 적용되며, 버전별로 다른 부분은 별도 표로 정리했습니다.


ORA-28547 에러란? — 공식 정의

ORA-28547: connection to server failed, probable Oracle Net admin error

공식 원인 (Oracle Database Error Messages 인용):

A failure occurred during initialization of a network connection from a client process to the Oracle server. The connection was completed but a disconnect occurred while trying to perform protocol-specific initialization, usually due to use of different network protocols by opposite sides of the connection.

쉽게 말하면 TCP 연결은 됐는데, 그 위에서 Oracle Net 프로토콜 협상이 깨진 상태입니다. 인증(ID/비밀번호) 단계 이전에 발생하므로 ORA-01017(invalid username/password)이나 ORA-12541(no listener)과는 결이 다릅니다.

비유하자면, 전화는 연결됐는데 두 사람이 서로 다른 언어로 인사하다가 통화가 끊긴 상황입니다.


ORA-28547 공식 원인 5가지 (Oracle Docs 기준)

순위 원인 적용 버전
1 connect string에 (HS=) 잘못 포함 11g~19c 동일
2 Database link / 외부 프로시저용 HS 에이전트 설정 오류 11g~19c 동일
3 클라이언트가 서버 character set 미인식 (ORA_NLS10) 11g~19c 동일
4 Windows + DRCP + SQLNET.AUTHENTICATION_SERVICES=NTS 11g R1~19c
5 Shared server 전부 busy + INBOUND_CONNECT_TIMEOUT 만료 11g~19c 동일

이 5가지가 공식 문서가 명시한 ORA-28547의 진짜 원인입니다. 비트 불일치, tnsnames 오타, 방화벽 차단 같은 항목은 다른 에러 코드의 영역이며, 본문 아래쪽 헷갈리는 다른 에러 코드 섹션에서 별도로 정리했습니다.


ORA-28547 단계별 해결법

1단계 — (HS=) 점검 (가장 흔함)

연결 문자열이나 tnsnames.ora에 (HS=)가 들어 있다면 Heterogeneous Services 에이전트로 라우팅됩니다. 일반 Oracle DB 접속에는 들어가면 안 되는 값입니다.

# 잘못된 예 — 일반 DB 연결인데 HS= 가 들어감
ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.10)(PORT = 1521))
    (CONNECT_DATA =
      (SID = ORCL)
    )
    (HS=OK)         # ← 이 라인을 지워야 합니다
  )

해결:

  • Heterogeneous Services를 의도적으로 쓰는 게 아니라면 (HS=) 라인 제거
  • 의도해서 쓴다면 HS 에이전트의 init<sid>.ora(예: initdg4odbc.ora)와 listener.oraPROGRAM=hsodbc / PROGRAM=dg4odbc 항목을 점검

2단계 — Character Set 확인

클라이언트의 ORA_NLS10 환경변수가 잘못 설정됐거나, 서버에 새로 추가된/사용자 정의 character set을 클라이언트가 인식 못 하는 경우입니다.

-- 서버 character set 확인
SELECT *
FROM nls_database_parameters
WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
# 클라이언트에서 ORA_NLS10 변수 확인
# Windows
echo %ORA_NLS10%

# Linux
echo $ORA_NLS10

해결:

  • 클라이언트 ORA_NLS10을 비워두거나 올바른 경로로 지정 (대부분 비워두는 게 정답)
  • 클라이언트 버전이 너무 낮으면 서버 character set을 못 따라가므로 클라이언트 업그레이드
  • 사용자 정의 character set을 쓴다면 클라이언트 쪽에도 동일하게 설치

3단계 — Windows DRCP + NTS 점검

DRCP(Database Resident Connection Pool)를 Windows에서 사용하면서 SQLNET.AUTHENTICATION_SERVICES=NTS인 경우 ORA-28547이 발생합니다.

# sqlnet.ora — Windows DRCP 환경
SQLNET.AUTHENTICATION_SERVICES = (NONE)

버전 호환: DRCP는 Oracle 11g R1(11.1)에서 도입되었습니다. 11g~19c 모든 버전에서 같은 증상이 발생할 수 있습니다.

4단계 — Shared Server 자원·타임아웃 확인

Shared server 모드에서 모든 shared server가 busy 상태일 때, SQLNET.INBOUND_CONNECT_TIMEOUT(기본 60초, 11g 이후 동일)이 만료되면 ORA-28547로 떨어집니다.

-- shared server 사용 현황
SELECT name, network, status, idle, busy
FROM v$dispatcher;

SELECT name, requests, busy, idle
FROM v$shared_server;

해결:

  • SHARED_SERVERS, MAX_SHARED_SERVERS 파라미터 상향
  • 또는 tnsnames.ora의 (CONNECT_DATA = ... (SERVER = DEDICATED) ...) 명시로 dedicated 강제
  • sqlnet.oraSQLNET.INBOUND_CONNECT_TIMEOUT_LISTENER 값을 늘려 일시적 회피 (근본 해결은 자원 확보)

5단계 — alert.log·trace에서 동반 에러 찾기

서버의 $ORACLE_BASE/diag/rdbms/<DB>/<SID>/trace/alert_<SID>.log(11g R1 이상, ADR 도입 후)에 ORA-28547과 함께 추가 단서가 찍힌 경우가 많습니다. 10g 이하·11g 이전 환경은 $ORACLE_HOME/admin/<SID>/bdump/alert_<SID>.log 경로입니다.


버전별 호환표 — 11g · 12c · 19c

항목 11g R2 12c 19c 운영 영향
ORA-28547 정의·공식 원인 5가지 동일 동일 동일 본문 1~5단계 모두 적용
인증 파라미터 SQLNET.ALLOWED_LOGON_VERSION (단일) _SERVER·_CLIENT 분리, 단일은 deprecated _SERVER·_CLIENT 권장, 단일은 desupport 대상 12c 이상 업그레이드 시 파라미터 이름 교체
DRCP 11.1부터 사용 가능 사용 가능 사용 가능 본문 3단계 동일 적용
alert.log 경로 diag/rdbms/... (ADR) 동일 동일 11g 이전은 bdump/
Premier / Extended Support 11.2.0.4: 2020-12 종료 12.2: 2022-03 종료 19c: 2027-04 / 2032-04 (예정) 11g·12c 운영 시 보안 패치 부재

11g 운영자 주의: Oracle 11.2.0.4의 모든 패치 지원은 2020년 12월에 종료됐습니다. ORA-28547 자체는 본 가이드대로 동일하게 해결되지만, OS·네트워크 보안 패치 갱신이 멈춰 있으므로 19c 마이그레이션을 권장합니다.


테스트·개발용 Oracle 도커 이미지 추천 (2026-05 기준)

ORA-28547을 로컬에서 재현하거나 버전별 동작을 검증할 때 어떤 도커 이미지를 쓰는 게 좋은지 용도별로 정리했습니다.

용도별 권장 이미지

용도 권장 이미지 라이선스 / 비고
빠른 로컬 개발 / 최신 기능 검증 container-registry.oracle.com/database/free Oracle 공식, 23ai Free, 무료
멀티 아치 (Apple Silicon · ARM64) gvenzl/oracle-free (23.5+) Oracle 직원이 메인테인, 멀티 플랫폼 빌드
19c · 21c 엔터프라이즈 동작 검증 container-registry.oracle.com/database/enterprise Oracle 계정·라이선스 동의 필요
11g R2 레거시 호환 검증 gvenzl/oracle-xe:11.2.0.2-slim x86_64 전용, ARM은 에뮬레이션 필요
디스크 절약·빠른 시작 gvenzl/oracle-free:slim 또는 :latest-lite 슬림 빌드, 일부 기능 제외

23ai Free — 현재 가장 권장 (라이선스·아키 모두 자유로움)

docker run -d \
  --name oracle-free \
  -p 1521:1521 \
  -e ORACLE_PWD=YourSecurePassword \
  container-registry.oracle.com/database/free:latest-lite

# 접속
sqlplus sys/YourSecurePassword@localhost:1521/FREEPDB1 as sysdba

서비스명은 FREE(CDB) 또는 FREEPDB1(기본 PDB). ORA-28547 재현/검증을 위해 sqlnet.ora를 손봐야 한다면 /opt/oracle/oradata/dbconfig/FREE/ 경로를 볼륨 마운트하세요.

Apple Silicon · ARM64 환경에서 주의

  • 23ai Free (23.5 이상) — 멀티 아치 이미지라 그대로 사용 가능
  • 11g / 18c / 21c XE — Oracle DB는 ARM 네이티브 포트가 없으므로 colima 등으로 x86_64 에뮬레이션 필요:
# colima로 x86_64 VM 띄우고 그 위에서 실행
colima start --arch x86_64 --memory 4
docker run -d --platform linux/amd64 \
  --name oracle-xe-11g \
  -p 1521:1521 \
  -e ORACLE_PASSWORD=YourSecurePassword \
  gvenzl/oracle-xe:11.2.0.2-slim

운영 환경에서의 주의

  • Oracle 공식 엔터프라이즈 이미지(container-registry.oracle.com/database/enterprise)는 상용 라이선스 동의가 필요합니다. 운영 용도라면 사내 라이선스 정책 확인 필수.
  • gvenzl/oracle-xe 같은 커뮤니티 XE 이미지는 개발·테스트 전용으로만 사용하세요. 운영은 공식 채널을 통한 라이선스된 환경에서.
  • ORA-28547 시나리오 중 DRCP·Shared Server 재현은 Free 이미지에서도 가능하지만 별도 파라미터 설정이 필요합니다 (ALTER SYSTEM SET shared_servers = ...).

한글 지원 — 어떤 character set을 쓸까

Oracle DB의 한글 처리는 character set 선택이 핵심입니다. 본문 2단계 — Character Set 확인에서 다뤘듯 클라이언트가 서버 character set을 못 따라가면 ORA-28547로 떨어질 수 있으므로, 도커 이미지를 고를 때부터 신경 써두는 게 좋습니다.

Character Set 권장 시나리오 비고
AL32UTF8 신규 환경 / 다국어 지원 Oracle 공식 권장, 23ai Free 기본값
KO16MSWIN949 레거시 운영 DB(Windows 한글) 미러링 빌드 시점에 변경 가능한 이미지 사용
KO16KSC5601 매우 오래된 레거시 호환 신규 시스템에선 비추천

케이스 1 — AL32UTF8 (대부분의 신규 환경, 권장)

23ai Free 이미지는 AL32UTF8이 기본값입니다. 별도 설정 없이 그대로 쓰면 한글이 정상 처리됩니다.

docker run -d \
  --name oracle-free \
  -p 1521:1521 \
  -e ORACLE_PWD=YourSecurePassword \
  container-registry.oracle.com/database/free:latest-lite

확인:

SELECT parameter, value
FROM nls_database_parameters
WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
-- NLS_CHARACTERSET = AL32UTF8

케이스 2 — KO16MSWIN949 (레거시 운영 DB 미러링)

운영 DB가 KO16MSWIN949로 돌고 있어 로컬에서 동일 환경 재현이 필요한 경우입니다.

이미지 선택 주의: 23ai Free 및 Oracle 공식 docker-images의 23c Free 이미지는 ORACLE_CHARACTERSET 환경변수를 줘도 AL32UTF8로 고정되는 알려진 제약이 있습니다(GitHub Issue #2673). 한글 KO16MSWIN949 환경을 재현하려면 gvenzl/oracle-xe처럼 빌드 시점에 character set을 받아주는 이미지를 사용하세요.

docker run -d \
  --name oracle-xe-kr \
  -p 1521:1521 \
  -e ORACLE_PASSWORD=YourSecurePassword \
  -e ORACLE_CHARACTERSET=KO16MSWIN949 \
  gvenzl/oracle-xe:21-slim-faststart

Apple Silicon에선 gvenzl/oracle-xe가 ARM 미지원이라 colima로 x86_64 에뮬레이션이 필요합니다(앞의 ARM64 섹션 참고).

클라이언트 NLS_LANG 설정 — 한글 깨짐 방지

컨테이너 character set과 별개로, 외부 클라이언트에서 한글을 입출력할 때NLS_LANG 환경변수가 핵심입니다.

자주 헷갈리는 포인트인데, NLS_LANG의 character set 부분은 서버가 아니라 "클라이언트 터미널/IDE의 실제 표시 인코딩"과 일치시켜야 합니다. 매칭이 어긋나면 Oracle이 잘못된 변환을 하고, 한글이 ???로 깨집니다.

클라이언트 환경 권장 NLS_LANG
macOS · Linux 터미널 (UTF-8) KOREAN_KOREA.AL32UTF8
Windows 명령 프롬프트 (cp949) KOREAN_KOREA.KO16MSWIN949
JDBC 애플리케이션 미설정 OK (드라이버가 자동 처리)
# Linux / macOS
export NLS_LANG=KOREAN_KOREA.AL32UTF8

# Windows PowerShell
$env:NLS_LANG = "KOREAN_KOREA.KO16MSWIN949"

# Windows cmd
set NLS_LANG=KOREAN_KOREA.KO16MSWIN949

서버 character set이 다르더라도 Oracle Net이 자동으로 변환해주므로, 클라이언트 표시 인코딩 기준으로 맞추는 게 정답입니다.

Instant Client 패키지 — Basic vs Basic Light

외부에서 Oracle 컨테이너에 접속할 때 쓰는 Oracle Instant Client는 BasicBasic Light(basiclite) 두 가지로 배포됩니다. 한글 환경이라면 어느 쪽을 받느냐가 character set 호환성과 직결되므로 신중히 골라야 합니다.

항목 Basic Basic Light (basiclite)
패키지 크기 큼 (~200MB) 작음 (~40MB)
에러 메시지 언어 전체 언어 영어만
지원 character set 약 250개 (전체) 8개로 제한
AL32UTF8 (Unicode)
KO16MSWIN949 / KO16KSC5601 ❌ → ORA-12737 발생
LANGUAGE / TERRITORY 자유 설정

Basic Light가 지원하는 character set은 다음 8개로 한정되며, 그 외 character set 서버에 접속하면 ORA-12737 에러가 납니다.

US7ASCII, WE8DEC, WE8MSWIN1252, WE8ISO8859P1,
WE8EBCDIC37C, WE8EBCDIC1047, UTF8, AL32UTF8

시나리오별 권장:

시나리오 권장 패키지
서버가 AL32UTF8 (대부분의 신규 환경) Basic Light OK
서버가 KO16MSWIN949 (레거시 한글 운영 DB) Basic 필수
컨테이너 이미지 크기 최소화 우선 Basic Light
한글 에러 메시지 / 다국어 메시지 필요 Basic

ORA-12737 주의: Basic Light로 KO16MSWIN949 서버에 접속하면 ORA-12737: Instant Client Light: unsupported server character set 에러가 납니다. NLS_LANG 조정으로는 회피되지 않으며, 풀 Basic 패키지로 교체가 유일한 해결입니다. 본문 ORA-28547과는 별개 에러이지만 한글 환경에서 자주 함께 등장합니다.

도커 이미지 안에서 sqlplus 등을 실행해야 한다면, Instant Client를 포함한 멀티스테이지 이미지를 빌드할 때 character set 매칭에 따라 Basic / Basic Light를 선택하세요.


헷갈리는 다른 에러 코드 — ORA-28547로 오해하기 쉬운 것들

검색하면 ORA-28547과 같이 묶여 나오지만, 공식적으로는 다른 에러 코드의 영역인 항목들입니다. ORA-28547로 보이더라도 alert.log에 아래 코드가 함께 찍혔다면 진짜 원인은 그쪽입니다.

증상 실제 에러 코드 공식 원인
32bit/64bit 클라이언트 비트 불일치 ORA-12705 / ORA-12537 NLS · 환경 부정합 / partner disconnected
tnsnames.ora 호스트·서비스명 오타 ORA-12154 / ORA-12541 TNS resolve 실패 / no listener
리스너에 서비스 미등록 ORA-12514 listener does not currently know of service
12c 클라이언트로 19c 서버 접속 실패 ORA-28040 No matching authentication protocol
방화벽이 1521 포트 차단 ORA-12170 / ORA-12541 TNS:Connect timeout / no listener
서버에서 갑자기 끊김 ORA-12537 (informational) partner disconnected (EOF) — 추가 단서 필요

애플리케이션 레벨 처리 — 운영 권장 패턴

// Spring + Resilience4j 예시
@Retryable(
    value = { SQLException.class },
    maxAttempts = 3,
    backoff = @Backoff(delay = 1000, multiplier = 2)
)
public Connection getConnection() throws SQLException {
    return dataSource.getConnection();
}

@Recover
public Connection recover(SQLException e) {
    log.error("DB 연결 실패 (errorCode={})", e.getErrorCode(), e);
    alertService.notifyOps("DB connection failure: " + e.getErrorCode());
    throw new ServiceUnavailableException("DB 일시 점검 중입니다.");
}

핵심 원칙:

  • ORA-28547처럼 일시적일 수 있는 에러(특히 shared server busy 시나리오)는 짧은 재시도로 흡수
  • 연속 실패 시 운영팀 알림, 사용자에게는 일반 메시지
  • HikariCP의 connectionTestQuery / validationTimeout으로 사전 차단

ORA-28547 자주 묻는 질문 (FAQ)

Q1. 운영 중인 서비스에서 갑자기 발생합니다. 가장 먼저 무엇을 봐야 하나요?

서버의 alert.loglistener.log를 동시에 확인해 ORA-28547과 함께 찍힌 동반 에러 코드를 찾으세요. 위 헷갈리는 다른 에러 코드 표에서 매칭되는 항목이 있다면 진짜 원인은 그쪽입니다.

Q2. tnsping은 성공하는데 sqlplus만 ORA-28547이 납니다.

tnsping은 리스너까지의 네트워크와 TNS resolve만 확인합니다. ORA-28547은 그 이후 단계인 세션 협상에서 깨지는 에러라 tnsping은 통과합니다. 본문 1·2·3·4단계를 차례로 점검하세요.

Q3. Database link 호출 시에만 ORA-28547이 납니다.

가장 흔한 정공 케이스입니다. Database link가 가리키는 tnsnames 항목에 (HS=)가 들어 있거나, HS 에이전트의 init<sid>.ora가 잘못된 경우입니다. 본문 1단계를 우선 점검하세요.

Q4. 12c 이하 클라이언트로 19c 서버에 붙는데 인증 호환 에러가 납니다.

이 시나리오는 ORA-28547이 아니라 ORA-28040 (No matching authentication protocol) 입니다. 19c 서버의 SQLNET.ALLOWED_LOGON_VERSION_SERVER 기본값이 12로 올라갔기 때문입니다. 임시 해결은 서버에서 값을 11로 낮추는 것이고, 근본 해결은 클라이언트를 19c로 업그레이드하는 것입니다.

Q5. 11g 환경에서도 본 가이드를 그대로 적용해도 되나요?

ORA-28547의 5가지 공식 원인은 11g R2부터 19c까지 동일합니다. 다만 위 버전별 호환표에 정리한 대로 인증 파라미터 이름(11g는 단일 SQLNET.ALLOWED_LOGON_VERSION)과 alert.log 경로(11g R1 이전은 bdump/)는 다릅니다. 11.2.0.4는 2020-12에 모든 패치 지원이 종료됐으므로 보안 측면에서 19c 마이그레이션을 권장합니다.


마무리 — 공식 원인 중심 체크리스트

ORA-28547을 만났을 때 위에서부터 차례로 확인하세요.

  • connect string · tnsnames에 (HS=)가 들어 있는가?
  • HS 에이전트(database link / 외부 프로시저)를 의도적으로 사용 중인가?
  • 클라이언트 ORA_NLS10 환경변수가 비정상적으로 설정돼 있는가?
  • Windows + DRCP 환경에서 SQLNET.AUTHENTICATION_SERVICES=NTS인가?
  • Shared server 모드에서 모든 server가 busy 상태인가?
  • alert.log에 동반 에러 코드가 함께 찍혀 있는가?

이 6가지가 모두 아니라면, 위 헷갈리는 다른 에러 코드 표로 넘어가서 ORA-28547이 진짜 원인인지부터 다시 확인하세요.

여러분이 만난 ORA-28547은 어느 케이스였나요? 댓글로 alert.log에 함께 찍혔던 동반 에러 코드를 공유해주시면 다음 글에 사례로 반영하겠습니다.


참고 자료

@JavaPark
AI 시대의 개발자 도구, 실전 경험을 공유합니다