안녕하세요, 자바파커입니다.
"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.ora의PROGRAM=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.ora의SQLNET.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-faststartApple 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는 Basic과 Basic 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.log와 listener.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에 함께 찍혔던 동반 에러 코드를 공유해주시면 다음 글에 사례로 반영하겠습니다.
참고 자료
- Oracle Database Error Messages — ORA-28547
- Oracle Database Error Messages — ORA-28040
- Oracle Database Error Messages — ORA-12537
- Oracle Net Services Administrator's Guide (19c)
- Parameters for the sqlnet.ora File (19c)
- Database Resident Connection Pool (DRCP) in Oracle 11g R1 — ORACLE-BASE
- Oracle Lifetime Support Policy
- Oracle Database 23ai Free — Apple Silicon ARM 지원 발표
- gvenzl/oracle-free Docker Hub
- gvenzl/oracle-xe Docker Hub
- Oracle 공식 docker-images GitHub 리포지토리
- GitHub Issue #2673 — Oracle 23c Free character set 변경 제약
- Oracle NLS_LANG FAQ
- Oracle Instant Client Light — Language and Character Set Requirements (18c)
- About Oracle Instant Client Basic Light (23c)