【Oracle】ORA-12154 完全ガイド|TNS: could not resolve the connect identifier specified の原因と解決方法

ORA-12154: TNS: could not resolve the connect identifier specified は、Oracle クライアントが指定された接続識別子(ネットサービス名)を解決できないときに発生するエラーです。SQL*Plus や JDBC、Python(cx_Oracle / python-oracledb)などから Oracle に接続しようとした際に頻繁に発生します。

簡単に言えば、接続先の名前が見つからないという状態です。tnsnames.ora に接続先が定義されていない・ファイルの場所が間違っている・記述にタイプミスがある、といった原因がほとんどです。

この記事でわかること

  • ORA-12154 が発生する主な原因(一覧表)
  • tnsnames.ora の正しい書き方と配置場所の確認方法
  • TNS_ADMIN 環境変数を確認・設定する方法
  • tnsping で接続テストをして問題を切り分ける方法
  • Easy Connect を使って tnsnames.ora なしで接続する方法
  • JDBC・Python・.NET など各言語での接続文字列の書き方
スポンサーリンク

ORA-12154 の主な原因

原因 詳細 確認方法
tnsnames.ora に接続先が定義されていない 指定したネットサービス名(例: ORCL)が tnsnames.ora に存在しない tnsnames.ora をテキストエディタで開いて確認
tnsnames.ora の場所が違う TNS_ADMIN が別のディレクトリを指している、またはファイルが見つからない echo $TNS_ADMIN / tnsping コマンドで確認
ネットサービス名のスペルミス 接続文字列に指定した名前と tnsnames.ora の定義名が不一致 大文字小文字は区別されないが、スペルミスに注意
tnsnames.ora の構文エラー 括弧の不一致・改行位置の問題・不正な文字が含まれている tnsping で確認。エラーが出る場合は構文を再確認
sqlnet.ora の NAMES.DIRECTORY_PATH 設定 TNSNAMES が含まれていない場合、tnsnames.ora が参照されない sqlnet.ora の NAMES.DIRECTORY_PATH を確認
Oracle Client 未インストール Oracle Instant Client をインストールしたが tnsnames.ora を配置していない Instant Client の場合は TNS_ADMIN の設定が必要

tnsnames.ora の正しい書き方と配置場所

tnsnames.ora の正しい記述例
# 基本的な書き方
ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = db-server.example.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl.example.com)
    )
  )

# 複数の接続先を定義する例
PROD_DB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.100)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = proddb)
    )
  )

DEV_DB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.200)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = devdb)
    )
  )

# よくある間違い①: 括弧の不一致(閉じ括弧が足りない)
# NG:
# ORCL =
#   (DESCRIPTION =
#     (ADDRESS = (PROTOCOL = TCP)(HOST = server1)(PORT = 1521))
#     (CONNECT_DATA =
#       (SERVICE_NAME = orcl)  ← ここで閉じ括弧が1つ足りない

# よくある間違い②: SID と SERVICE_NAME の取り違え
# SID は古い形式(Oracle 8i 以前):
#   (CONNECT_DATA = (SID = orcl))
# SERVICE_NAME は新しい形式(推奨):
#   (CONNECT_DATA = (SERVICE_NAME = orcl))
# ※ RAC 環境では SERVICE_NAME の使用が必須

# よくある間違い③: ネットサービス名の前後に余分なスペース
# NG: " ORCL " = ...   ← 前後のスペースが原因で一致しない場合がある

TNS_ADMIN 環境変数と tnsnames.ora の配置場所を確認する

Oracle クライアントは以下の順序で tnsnames.ora を検索します。

  1. TNS_ADMIN 環境変数で指定されたディレクトリ
  2. $ORACLE_HOME/network/admin(TNS_ADMIN が未設定の場合)
TNS_ADMIN と tnsnames.ora の配置を確認する(Linux / macOS)
# TNS_ADMIN の現在値を確認する
echo $TNS_ADMIN
# 空の場合は $ORACLE_HOME/network/admin が使われる

# ORACLE_HOME を確認する
echo $ORACLE_HOME
# 例: /u01/app/oracle/product/19.3.0/dbhome_1

# tnsnames.ora の実際の場所を確認する
ls -la $TNS_ADMIN/tnsnames.ora 2>/dev/null || ls -la $ORACLE_HOME/network/admin/tnsnames.ora

# Oracle Instant Client を使っている場合は TNS_ADMIN を明示的に設定する
export TNS_ADMIN=/opt/oracle/instantclient_19_22/network/admin
# ~/.bashrc や ~/.bash_profile に追記して永続化する
echo 'export TNS_ADMIN=/opt/oracle/instantclient_19_22/network/admin' >> ~/.bashrc

# tnsnames.ora の内容を確認する
cat $TNS_ADMIN/tnsnames.ora
TNS_ADMIN と tnsnames.ora の配置を確認する(Windows)
# TNS_ADMIN の現在値を確認する(コマンドプロンプト)
echo %TNS_ADMIN%

# PowerShell で確認する
$env:TNS_ADMIN

# ORACLE_HOME を確認する
echo %ORACLE_HOME%
# 例: C:\app\oracle\product\19.3.0\dbhome_1

# tnsnames.ora の場所
# %TNS_ADMIN%\tnsnames.ora
# または %ORACLE_HOME%\network\admin\tnsnames.ora

# レジストリに設定されている場合もある
# HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraClient19Home1\TNS_ADMIN

# 環境変数を設定する(システムのプロパティ → 環境変数)
# 変数名: TNS_ADMIN
# 変数値: C:\app\oracle\product\19.3.0\dbhome_1\network\admin

tnsping で接続テストをして原因を切り分ける

tnsping で名前解決の成否を確認する
# tnsnames.ora で定義したネットサービス名を指定する
tnsping ORCL

# 成功時の出力例:
# TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production
# Used parameter files:
# /u01/app/oracle/product/19.3.0/dbhome_1/network/admin/sqlnet.ora
#
# Used TNSNAMES adapter to resolve the alias
# Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = db-server)(PORT = 1521))
# (CONNECT_DATA = (SERVICE_NAME = orcl)))
# OK (10 msec)

# 失敗時の出力例(ORA-12154):
# TNS-03505: Failed to resolve name

# tnsping で確認できるポイント:
# 1. "Used parameter files:" → sqlnet.ora のパス(TNS_ADMIN が正しいか)
# 2. "Used TNSNAMES adapter" → tnsnames.ora を使って解決を試みたか
# 3. "Attempting to contact" → 解決された接続情報(HOST/PORT/SERVICE_NAME)
# 4. "OK (xx msec)" → 名前解決+リスナーへの疎通が成功

# tnsping は名前解決とリスナー接続を確認する
# DB への認証(ユーザー名/パスワード)は確認しない
# → tnsping が成功しても ORA-01017 が出る場合は認証の問題

# tnsping が失敗する場合のチェックリスト:
# 1. 指定した名前のスペルが tnsnames.ora と一致しているか
# 2. TNS_ADMIN が正しいか(echo $TNS_ADMIN で確認)
# 3. tnsnames.ora の構文にエラーがないか(括弧の対応)
# 4. sqlnet.ora の NAMES.DIRECTORY_PATH に TNSNAMES が含まれているか

sqlnet.ora の NAMES.DIRECTORY_PATH を確認する

sqlnet.ora の名前解決設定
# sqlnet.ora の場所: $TNS_ADMIN/sqlnet.ora または $ORACLE_HOME/network/admin/sqlnet.ora

# NAMES.DIRECTORY_PATH: 名前解決の方式と優先順位を設定する
NAMES.DIRECTORY_PATH = (TNSNAMES, LDAP, EZCONNECT)

# TNSNAMES: tnsnames.ora ファイルを使う(最も一般的)
# LDAP: Oracle Internet Directory(OID)を使う
# EZCONNECT: Easy Connect 方式を使う(host:port/service_name)

# ★ ORA-12154 の原因: TNSNAMES が含まれていない場合
# NG(TNSNAMES がないので tnsnames.ora が参照されない):
# NAMES.DIRECTORY_PATH = (LDAP)

# ★ 修正: TNSNAMES を追加する
# NAMES.DIRECTORY_PATH = (TNSNAMES, LDAP, EZCONNECT)

# sqlnet.ora がない場合はデフォルトで (TNSNAMES, EZCONNECT) が使われる
# → ファイルがない場合に ORA-12154 が出るなら tnsnames.ora 側の問題

# その他の関連設定
SQLNET.AUTHENTICATION_SERVICES = (NTS)   # Windows 認証を使う場合
# SQLNET.AUTHENTICATION_SERVICES = (NONE) # パスワード認証のみ

Easy Connect を使って tnsnames.ora なしで接続する

tnsnames.ora の設定が面倒な場合や、一時的な接続テストには Easy Connectが便利です。ホスト名:ポート/サービス名 の形式で直接接続先を指定できます。

Easy Connect による接続例
# Easy Connect の基本構文
# sqlplus ユーザー名/パスワード@ホスト名:ポート/サービス名

# SQL*Plus での接続例
sqlplus hr/password@db-server.example.com:1521/orcl

# IP アドレスで接続する
sqlplus hr/password@192.168.1.100:1521/orcl

# ポート番号を省略する(デフォルト 1521 が使われる)
sqlplus hr/password@db-server.example.com/orcl

# Oracle 19c 以降の Easy Connect Plus(追加オプション)
sqlplus hr/password@"db-server.example.com:1521/orcl?connect_timeout=10&transport_connect_timeout=3"

# Python(python-oracledb / cx_Oracle)での Easy Connect
# import oracledb
# conn = oracledb.connect(
#     user="hr",
#     password="password",
#     dsn="db-server.example.com:1521/orcl"
# )

# tnsping でも Easy Connect を確認できる
tnsping db-server.example.com:1521/orcl

各言語での接続文字列の書き方

JDBC(Java)での接続文字列
-- JDBC Thin ドライバ(tnsnames.ora 不要)
-- jdbc:oracle:thin:@ホスト名:ポート:SID
-- jdbc:oracle:thin:@ホスト名:ポート/サービス名(推奨)
-- jdbc:oracle:thin:@//ホスト名:ポート/サービス名(URL 形式)

-- 例:
-- String url = "jdbc:oracle:thin:@db-server.example.com:1521/orcl";
-- String url = "jdbc:oracle:thin:@//db-server.example.com:1521/orcl";

-- TNS 名を使う場合(tnsnames.ora が必要)
-- String url = "jdbc:oracle:thin:@ORCL";
-- → TNS_ADMIN が Java プロセスから参照できる必要がある
-- System.setProperty("oracle.net.tns_admin", "/path/to/tns_admin");

-- 接続記述子を直接 JDBC 文字列に埋め込む
-- String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)"
--     + "(HOST=db-server.example.com)(PORT=1521))"
--     + "(CONNECT_DATA=(SERVICE_NAME=orcl)))";
JDBC で ORA-12154 が出た場合のチェックポイント

  • Thin ドライバを使う場合は @//host:port/service 形式なら tnsnames.ora は不要
  • TNS 名(@ORCL など)を使う場合は oracle.net.tns_admin プロパティの設定が必要
  • SID 形式(@host:port:SID)と SERVICE_NAME 形式(@host:port/service)を間違えると接続できない
Python(python-oracledb / cx_Oracle)での接続文字列
# python-oracledb(推奨・Oracle 公式)
import oracledb

# Thin モード(Oracle Client 不要・tnsnames.ora 不要)
conn = oracledb.connect(
    user="hr",
    password="password",
    dsn="db-server.example.com:1521/orcl"  # Easy Connect 形式
)

# Thick モード(Oracle Client 必要)
# oracledb.init_oracle_client(lib_dir="/opt/oracle/instantclient_19_22")
# conn = oracledb.connect(user="hr", password="password", dsn="ORCL")

# 接続記述子を直接指定する(tnsnames.ora 不要)
dsn = """(DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCP)(HOST=db-server.example.com)(PORT=1521))
    (CONNECT_DATA=(SERVICE_NAME=orcl)))"""
conn = oracledb.connect(user="hr", password="password", dsn=dsn)

# TNS_ADMIN を明示的に設定する(Thick モード + tnsnames.ora 使用時)
# oracledb.init_oracle_client(
#     lib_dir="/opt/oracle/instantclient_19_22",
#     config_dir="/opt/oracle/instantclient_19_22/network/admin"
# )

よくある落とし穴と解決パターン

状況 原因 解決方法
sqlplus では接続できるが アプリケーションから接続できない アプリケーションの TNS_ADMIN が異なる、または Oracle Client が別のもの アプリケーションプロセスの環境変数を確認する
Linux では接続できるが Windows からできない Windows の TNS_ADMIN がレジストリ経由で設定されている場合がある レジストリの HKLM\SOFTWARE\ORACLE を確認する
Oracle Instant Client を使っているが接続できない Instant Client には network/admin ディレクトリがデフォルトでない TNS_ADMIN を設定するか Easy Connect を使う
tnsping は成功するが接続できない tnsping は名前解決のみ。ORA-12154 以外のエラー(12514/01017 等)の可能性 エラーコードを再確認する(12514 はサービス名が違う、01017 はパスワード誤り)
tnsnames.ora を編集したが反映されない tnsnames.ora はキャッシュされる場合がある アプリケーションを再起動する。lsnrctl reload は不要(クライアント側の問題)
Docker コンテナ内から接続できない コンテナ内に tnsnames.ora がコピーされていない TNS_ADMIN をマウントするか Easy Connect を使う

まとめ

  • ORA-12154 は「接続先の名前が見つからない」エラー。tnsnames.ora の記述ミス・TNS_ADMIN の不一致・sqlnet.ora の設定が主な原因
  • 切り分けの手順:① tnsping で名前解決を確認 → ② TNS_ADMIN の値を確認 → ③ tnsnames.ora の構文を確認 → ④ sqlnet.ora の NAMES.DIRECTORY_PATH を確認
  • tnsnames.ora の注意点:括弧の対応・SID と SERVICE_NAME の使い分け・前後のスペースに注意。tnsnames.ora がないディレクトリを TNS_ADMIN に設定しているケースが多い
  • Easy Connect が最も手軽host:port/service_name 形式なら tnsnames.ora が不要。テストや開発環境ではまず Easy Connect で接続確認するのが効率的
  • アプリケーション固有の注意点:JDBC Thin は TNS 名を使う場合 oracle.net.tns_admin の設定が必要。python-oracledb の Thin モードなら Oracle Client 自体が不要

名前解決の成功後にリスナー関連のエラーが出る場合はOracle ネットワーク設定完全ガイドを参照してください。パスワード認証のエラー(ORA-01017)についてはOracle ORA-01017 完全ガイドを参照してください。