PostgreSQLのエラー「could not translate host name to address」の解決:DNS問題の修正

beginner🐘 PostgreSQL2026-06-16| Linux (Ubuntu/Debian/CentOS), Docker, Kubernetes, AWS RDS/Cloud SQL

Error Message

could not translate host name "db.example.com" to address: Name or service not known
#postgresql#接続#dns#ホスト名#ネットワーク#トラブルシューティング

エラーメッセージ

データベースに接続しようとした際、パスワードの入力プロンプトではなく、次のような無機質なメッセージが表示されることがあります。

psql: error: could not connect to server: could not translate host name "db.example.com" to address: Name or service not known

実のところ、PostgreSQL自体が原因ではありません。このエラーは、オペレーティングシステムのネットワークスタックから発生しています。つまり、システムが db.example.com のIPアドレスを見つけようとしたものの、何も見つからなかったことを意味します。OSが名前をIPアドレスにマッピングできない場合、接続は開始される前に終了してしまいます。

主な原因は何でしょうか?

DNS(Domain Name System)は、インターネットの電話帳のようなものです。psqlにホスト名を指定すると、OSはそれを 10.0.5.42 のような数値のIPアドレスに変換する必要があります。このルックアップに失敗すると、ハンドシェイクは行われません。

よくある原因として、以下を確認してください。

  • 単純なタイポ(入力ミス): .env ファイルや接続文字列内のホスト名の綴り間違い。
  • DNSに到達できない: 設定されたネームサーバー(8.8.8.8 など)がダウンしているか、ファイアウォールによってブロックされている。
  • VPN/VPCの分離: 適切なVPCに接続されていない状態で、プライベートなAWS RDSインスタンスにアクセスしようとしている。
  • ローカルマッピングの不足: ホスト名がカスタムエイリアスであり、/etc/hosts に追加されていない。
  • Dockerの分離: アプリ用コンテナとデータベース用コンテナがネットワークを共有していない。

ステップバイステップの解決策

1. タイポ(入力ミス)を確認する

当たり前のことのように思えますが、文字が1つ違うだけで接続は失敗します。ホスト変数の前後に余計なスペースがないか、ドットが抜けていないかを確認してください。

# 誤り - 文字が不足している
psql -h db.postgre.com -U postgres

# 正しい例
psql -h db.postgres.com -U postgres

2. 手動で接続をテストする

推測に頼らず、OSが何を認識しているかを確認しましょう。標準的なネットワークツールを使用して、ホストがそもそも存在するかどうかを調べます。ターミナルから以下のコマンドを実行してください。

# 基本的なレスポンスを確認する
ping db.example.com

# DNSサーバーに直接問い合わせる
nslookup db.example.com

# 完全なDNSトレースを取得する(デバッグに最適)
dig db.example.com

もしこれらのコマンドが "NXDOMAIN" や "Name or service not known" を返した場合、問題はPostgreSQLではなくDNSの設定にあります。

3. /etc/hosts でローカルマッピングを強制する

パブリックなDNSレコードがないローカルの開発サーバーで作業している場合は、手動でマッピングする必要があります。これにより、DNSサーバーを完全にバイパスできます。

LinuxまたはmacOSでは、hostsファイルを開きます。

sudo nano /etc/hosts

ファイルの末尾にIPアドレスとホスト名を追加します。例えば、サーバーのIPが 192.168.1.105 の場合は以下のようになります。

192.168.1.105    db.example.com

保存して、再度接続を試してください。これは優れたクイックフィックス(応急処置)ですが、本番環境のスケーリングにおいてはこれに頼らないようにしましょう。

4. DNSリゾルバを修復する

サーバーがどの外部サイトも解決できない場合、resolv.conf が空であるか、破損している可能性があります。

cat /etc/resolv.conf

ネームサーバーが見当たらない場合は、GoogleやCloudflareなどの信頼できるものを一時的に追加して、オンラインに戻すことができます。

nameserver 8.8.8.8
nameserver 1.1.1.1

5. Dockerとコンテナネットワーク

Dockerでは、通常、コンテナ同士はサービス名で名前解決を行います。app コンテナが db コンテナを認識できない場合、おそらく同じ仮想ネットワーク上にありません。

# docker-compose.yml のスニペット例
services:
  db:
    image: postgres
    networks:
      - backend
  app:
    networks:
      - backend
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/dbname # 'db' がホスト名になります

composeファイル内で、両方のサービスが同じネットワークブロックを共有していることを確認してください。

修正の確認

設定を調整したら、-h フラグを指定して psql を実行し、接続が生きているか確認します。

psql -h db.example.com -U your_username -d your_database -W

Password for user ...: というプロンプトや、PostgreSQLのシェル(=>)が表示されれば、DNSのハードルをクリアしたことになります。

予防とベストプラクティス

ホスト名はハードコードされたIPアドレスよりも安全ですが、安定した基盤が必要です。以下のヒントを参考に、ネットワークの回復力を維持しましょう。

  • マネージドDNSを使用する: 本番環境では、脆弱な /etc/hosts エントリではなく、AWS Route53のプライベートゾーンやCloudflareを使用してください。
  • サービスディスカバリ: Kubernetesでは、ポッドが再起動しても安定したアドレッシングを確保するために、内部サービス名(例:db.default.svc.cluster.local)を使用します。
  • サブネットを計画する: 適切なネットワーク計画はルーティングループを防ぎます。私はCIDR範囲を正確にマッピングするために、IP Subnet Calculator を使用しています。これにより、DNSサーバーとデータベースノードが到達可能なセグメントに配置され、分離されたサブネットによる「address not known」エラーを回避できます。
  • TTLを意識する: データベースを最近移動した場合は、TTLの設定に応じてDNSレコードの伝播に5分から60分かかる場合があることを覚えておいてください。

Related Error Notes