DNS_PROBE_FINISHED_NXDOMAINの原因と直し方|digで切り分ける

実務レシピ

ブラウザにDNS_PROBE_FINISHED_NXDOMAINと表示されたときは、「DNSに問い合わせた結果、そのドメインは存在しないと返ってきた」状態です。通信そのものが切れているわけではなく、原因はドメイン名の解決(名前解決)の一点に絞り込めます。ブラウザの再読み込みを繰り返す前に、まず次のコマンドでDNSの応答を直接確認してください。

dig +noall +comments example.com | grep -o 'status: [A-Z]*'

ここでNXDOMAINが返ればブラウザの表示と同じ結論、NOERRORが返るならブラウザ側やキャッシュ側の問題です。この記事では、Ubuntu 24.04(dig 9.18)で実際に実行した出力をもとに、原因の切り分けから対処までをまとめます。

DNS_PROBE_FINISHED_NXDOMAINとは何か

エラー名は2つの部分に分かれます。DNS_PROBE_FINISHEDは「DNSへの問い合わせは最後まで完了した」、NXDOMAINは「Non-Existent Domain=そのドメインは存在しない」という意味です。つまり、DNSサーバーには届いていて、返ってきた答えが「ない」だった、ということになります。

ここが重要なポイントで、「ネットにつながっていない」わけではありません。DNSサーバーとは正常に通信できています。したがって、疑うべきは次の3つに絞られます。

  1. 入力したドメイン名が間違っている(タイプミス、存在しないサブドメイン)
  2. 自分の端末やルーターに、古い・誤った名前解決の設定やキャッシュが残っている
  3. サイト側のDNSレコードが消えている、またはドメインが失効している

ブラウザによって表示される文言は違う

同じNXDOMAINでも、ブラウザによって表示は変わります。文言が違っても原因は同じなので、下の表で自分の状況を読み替えてください。

ブラウザ/環境表示される内容
Google Chrome / EdgeDNS_PROBE_FINISHED_NXDOMAIN「このサイトにアクセスできません」
Firefox「サーバーが見つかりませんでした」
Safari「サーバが見つかりません」
Linux(curl)curl: (6) Could not resolve host: ...
Linux(ping)ping: ...: Name or service not known

最初にやること:自分側かサイト側かを切り分ける

対処法を片っ端から試すのは遠回りです。digを使えば、「自分の環境の問題」か「ドメインが本当に存在しない」かを最初の1コマンドで判別できます。

digでDNSの応答コードを確認する

存在しないドメインを引くと、次のような応答が返ります。

dig this-domain-does-not-exist-bashdo-test.com
; <<>> DiG 9.18.39-0ubuntu0.24.04.5-Ubuntu <<>> this-domain-does-not-exist-bashdo-test.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 42756
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;this-domain-does-not-exist-bashdo-test.com. IN A

;; AUTHORITY SECTION:
com.			900	IN	SOA	a.gtld-servers.net. nstld.verisign-grs.com. 1785640857 1800 900 604800 900

;; Query time: 17 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)

見るべき行は2つです。

  • status: NXDOMAIN … ブラウザのエラーと同じ結論。ドメインが存在しない
  • AUTHORITY SECTIONcom.のSOAが出ている … .comを管理する上位サーバーが「そんな名前は登録されていない」と答えた証拠

逆に正常なドメインならstatus: NOERRORになり、ANSWER SECTIONにIPアドレスとTTLが並びます。

dig bashdo.com | grep -A2 'ANSWER SECTION'
;; ANSWER SECTION:
bashdo.com.		3600	IN	A	183.90.183.141

ステータスだけを素早く取り出したいときは、次のように絞り込むと1行で済みます。

dig +noall +comments bashdo.com | awk '/status:/{print $6}' | tr -d ','
NOERROR

外部DNS(8.8.8.8 / 1.1.1.1)と結果を比べる

ここが切り分けの核心です。@サーバーを付けると、普段使っているDNSサーバーを迂回して直接問い合わせできます。

dig @8.8.8.8 +noall +comments example.com | grep -o 'status: [A-Z]*'
dig @1.1.1.1 +noall +comments example.com | grep -o 'status: [A-Z]*'

判定は次のとおりです。

手元のDNS8.8.8.8 / 1.1.1.1判断
NXDOMAINNXDOMAINドメインが本当に存在しない。URLの綴りかサイト側の問題
NXDOMAINNOERROR自分側の問題。DNSサーバー・キャッシュ・VPN・広告ブロッカーを疑う
NOERRORNOERRORDNSは正常。ブラウザのキャッシュや拡張機能、hostsファイルを疑う

実際に存在しないドメインで試すと、どのサーバーでも同じ答えになります。

$ dig @8.8.8.8 +noall +comments this-domain-does-not-exist-bashdo-test.com | grep -o 'status: [A-Z]*'
status: NXDOMAIN

statusごとの意味と次の一手

NXDOMAIN以外が返ることもあります。混同しやすいので整理しておきます。

status意味次にやること
NXDOMAINそのドメイン名は存在しない綴りを確認 → hosts/キャッシュ確認 → サイト側のDNS確認
NOERROR問い合わせは成功(レコードが0件のこともある)ANSWER: 0ならAレコード自体が未設定。ブラウザ側も疑う
SERVFAILDNSサーバー側で処理に失敗(DNSSEC検証失敗など)別のDNSサーバーで引き直す。ブラウザは別のエラーを出すことが多い
REFUSED問い合わせを拒否された社内DNSやフィルタリングDNSを使っていないか確認
応答なし/タイムアウトDNSサーバーまで届いていないNXDOMAINとは別問題。回線・ルーター側を確認

参考までに、DNSSEC検証に失敗するテスト用ドメインを引くとSERVFAILになります。

$ dig +noall +comments dnssec-failed.org | grep -o 'status: [A-Z]*'
status: SERVFAIL

host・nslookup・getent・curlでの見え方の違い

同じNXDOMAINでも、コマンドによってメッセージも終了ステータスも変わります。スクリプトに組み込むときはここを間違えると誤判定します。

$ host this-domain-does-not-exist-bashdo-test.com
Host this-domain-does-not-exist-bashdo-test.com not found: 3(NXDOMAIN)
$ echo $?
1

$ nslookup this-domain-does-not-exist-bashdo-test.com
Server:		127.0.0.1
Address:	127.0.0.1#53

** server can't find this-domain-does-not-exist-bashdo-test.com: NXDOMAIN
$ echo $?
1

$ getent hosts this-domain-does-not-exist-bashdo-test.com
$ echo $?
2

$ curl -sS https://this-domain-does-not-exist-bashdo-test.com/
curl: (6) Could not resolve host: this-domain-does-not-exist-bashdo-test.com
$ echo $?
6

$ ping -c1 this-domain-does-not-exist-bashdo-test.com
ping: this-domain-does-not-exist-bashdo-test.com: Name or service not known
$ echo $?
2
コマンドNXDOMAIN時の終了ステータス特徴
host11行で結果が出る。判定用に最も扱いやすい
nslookup1WindowsとLinuxで共通して使える
getent hosts2/etc/hostsも含めた「OSが実際に使う結果」がわかる
curl6名前解決の失敗だけを表す専用の終了コード
ping2ICMPが遮断される環境では判定に使えない
dig +short0失敗しても0を返す。判定には使わないこと

最後の行が実際によくある落とし穴です。dig +shortはNXDOMAINでも何も出力せずに終了ステータス0を返すため、if dig +short "$domain"; thenのような書き方では失敗を検出できません。

$ dig +short this-domain-does-not-exist-bashdo-test.com
$ echo $?
0

シェルスクリプトで名前解決の成否を判定するなら、hostgetent hostsを使うか、dig +shortの出力が空でないかを確認してください。

if [ -n "$(dig +short "$domain")" ]; then
  echo "解決できた"
else
  echo "解決できない"
fi

自分の環境が原因のときの対処

外部DNSではNOERROR、手元ではNXDOMAIN——このパターンなら、以下を上から順に確認します。

1. URLの綴りを疑う

もっとも多い原因です。.com.coと打ち間違えただけで、当然NXDOMAINになります。

$ dig +noall +comments bashdo.co | grep -o 'status: [A-Z]*'
status: NXDOMAIN

特にスマートフォンでは、日本語入力から切り替えずに全角文字が混ざるケースが起きがちです。検索エンジン経由でリンクを開き直すと、この種のミスは一発で切り分けられます。

2. /etc/hostsの古いエントリを消す

開発時にサーバーのIPを直書きして、そのまま消し忘れているケースです。/etc/hostsはDNSより先に参照されるため、ここに誤った行があるとDNSがどれだけ正常でも解決に失敗します。

grep -w example.com /etc/hosts

参照順は/etc/nsswitch.confで決まっています。files(=/etc/hosts)がdnsより前にあることを確認してください。

$ grep ^hosts /etc/nsswitch.conf
hosts:          files mdns4_minimal [NOTFOUND=return] dns

DNSと/etc/hostsのどちらが効いているかは、diggetent hostsの結果を比べればわかります。digはDNSに直接聞くため/etc/hostsを見ませんが、getent hostsはOSと同じ順序で解決します。2つの結果が食い違ったら、/etc/hostsが原因です。

WindowsではC:\Windows\System32\drivers\etc\hosts、macOSでは/etc/hostsが同じ役割を持ちます。

3. DNSキャッシュをクリアする

ドメインの引っ越し直後などは、古い「存在しない」という結果がキャッシュに残っていることがあります(ネガティブキャッシュ)。OSごとの手順は次のとおりです。

環境コマンド
Windowsipconfig /flushdns(管理者権限のコマンドプロンプト)
macOSsudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
Linux(systemd-resolved)sudo resolvectl flush-caches
Linux(dnsmasq)sudo systemctl restart dnsmasq
Linux(nscd)sudo nscd -i hosts
Chromeアドレスバーにchrome://net-internals/#dnsを開き「Clear host cache」

ここで見落としやすいのが、Linuxではそもそもキャッシュが存在しないことがあるという点です。glibc自体はDNS結果をキャッシュしないため、systemd-resolvedやdnsmasqのようなローカルリゾルバが動いていなければ、クリアするものがありません。まず何が動いているかを確認してください。

systemctl is-active systemd-resolved
cat /etc/resolv.conf
ss -lntup | grep ':53'

この記事の検証環境では、systemctl is-active systemd-resolvedinactiveを返し、/etc/resolv.confのnameserverは127.0.0.1ssでは127.0.0.1:53を掴む別のプロセスが見つかりました。この場合、resolvectl flush-cachesを実行しても次のように失敗します。

$ resolvectl flush-caches
Failed to flush caches: Unit dbus-org.freedesktop.resolve1.service not found.

つまり「ネットで見た手順を実行したのにエラーが出る」場合、手順が間違っているのではなく、その環境ではそのリゾルバを使っていないだけです。/etc/resolv.confのnameserverが127.0.0.53ならsystemd-resolved、それ以外のローカルアドレスならdnsmasq等の別プロセス、外部のIPが直接書かれているならローカルキャッシュ自体が無い、と読み替えられます。

4. 参照するDNSサーバーを変更する

プロバイダのDNSが不調な場合は、参照先をGoogle Public DNS(8.8.8.8 / 8.8.4.4)やCloudflare(1.1.1.1 / 1.0.0.1)に変更します。dig @8.8.8.8で結果が変わった場合の恒久対処がこれです。

NetworkManagerを使っているLinuxデスクトップなら、nmcliで接続単位に設定します(/etc/resolv.confを直接編集しても、多くの環境では再接続時に上書きされます)。

# 接続名を確認する
nmcli connection show

# DNSサーバーを設定して反映する
sudo nmcli connection modify "接続名" ipv4.dns "1.1.1.1 8.8.8.8"
sudo nmcli connection modify "接続名" ipv4.ignore-auto-dns yes
sudo nmcli connection up "接続名"

設定後は、必ず反映結果を確認します。

cat /etc/resolv.conf
dig +noall +comments example.com | grep -o 'status: [A-Z]*'

なお、社内ネットワークや学校のネットワークでは、内部ホスト名の解決に指定のDNSが必要なことがあります。外部DNSに変更すると今度は社内システムが引けなくなるため、業務環境では管理者に確認してから変更してください。

5. VPN・広告ブロッカー・セキュリティソフトを一時停止する

「特定のサイトだけ開けない」場合は、この線が濃厚です。広告ブロッカーやフィルタリングDNS(Pi-holeなど)は、ブロック対象のドメインに対して意図的にNXDOMAINを返す実装があります。つまりエラー自体は正常動作です。

切り分けは簡単で、外部DNSへ直接問い合わせて結果が変われば、手元のフィルタが原因だと確定します。

dig +noall +comments example.com | grep -o 'status: [A-Z]*'      # 手元のDNS
dig @1.1.1.1 +noall +comments example.com | grep -o 'status: [A-Z]*'  # 外部DNS

VPN接続中は、VPN側のDNSサーバーが使われます。VPNを切断して解決するなら、VPN事業者のDNSかトンネル設定が原因です。

6. ルーターを再起動する

家庭用ルーターはDNSプロキシとして動き、内部にキャッシュを持ちます。端末側のキャッシュを消しても直らないときは、ルーターの電源を30秒ほど切ってから入れ直してください。この操作の前後でdigの結果を記録しておくと、効果があったかどうかを判断できます。

サイト運営者側が原因のときの確認

どのDNSサーバーで引いてもNXDOMAINなら、ドメイン側の問題です。自分のサイトで発生した場合は、次の順で確認します。

Aレコードが存在するか(www有無に注意)

「wwwなしは開くが、wwwありでNXDOMAIN」は典型的な設定漏れです。両方を必ず確認してください。

dig +short A example.com
dig +short A www.example.com

逆に、ワイルドカードレコード(*.example.com)を設定していると、存在しないサブドメインでもNXDOMAINにならずNOERRORが返ります。「打ち間違えたサブドメインなのになぜかエラーにならない」場合は、ワイルドカードの有無を疑ってください。

$ dig +noall +comments nosuchhost.bashdo.com | grep -o 'status: [A-Z]*'
status: NOERROR

ネームサーバーの委任を確認する

レジストラ側でネームサーバーを変更した直後は、委任が正しく反映されているかを確認します。

$ dig +short NS bashdo.com
ns1.rakko.zone.
ns2.rakko.zone.

ここが空なら、そもそもDNSサーバーが割り当てられていません。ルートから順に辿って、どの段階で切れているかを見るには+traceを使います。

dig +trace example.com

DNS変更直後ならTTLと伝播を確認する

レコードを追加した直後でも、それ以前の「存在しない」という応答がキャッシュに残っている間はNXDOMAINが返り続けます。この保持時間はSOAレコードの最後の値(ネガティブキャッシュTTL)で決まります。

$ dig this-domain-does-not-exist-bashdo-test.com | grep -A1 'AUTHORITY SECTION'
;; AUTHORITY SECTION:
com.			900	IN	SOA	a.gtld-servers.net. nstld.verisign-grs.com. 1785640857 1800 900 604800 900

この例では末尾の900がネガティブキャッシュTTL(秒)です。つまり最大15分は、キャッシュサーバーが「存在しない」という答えを覚えたままになります。設定を直した直後に反映されないのは異常ではないので、権威サーバーに直接問い合わせて正しく応答するかだけを先に確認しておくのが確実です。

# 権威サーバーを取得して、そこへ直接問い合わせる
ns=$(dig +short NS example.com | head -1)
dig @"$ns" +noall +answer example.com

ドメインの有効期限切れを疑う

更新を忘れてドメインが失効すると、レジストリから委任が外れてNXDOMAINになります。whoisコマンドで登録状態と有効期限を確認します。

# 未インストールなら先に導入する(Ubuntu/Debian)
sudo apt install whois

whois example.com | grep -iE 'Expiry|Expiration|Status'

whoisは多くのディストリビューションで初期状態では入っていません(command not foundになったらインストールしてください)。ステータスにclientHoldredemptionPeriodが出ていれば、失効・停止が原因と判断できます。

切り分けを自動化するBashスクリプト

ここまでの確認を1本にまとめたスクリプトです。ドメイン名を渡すだけで、hostsからDNS委任までを一気に確認できます。

#!/bin/bash
# 使い方: ./dns-check.sh example.com
domain="$1"
[ -z "$domain" ] && { echo "usage: $0 <domain>"; exit 1; }

echo "== 1. ローカル設定 (/etc/hosts) =="
grep -w "$domain" /etc/hosts || echo "  /etc/hosts に該当なし(正常)"

echo "== 2. 通常の名前解決 =="
getent hosts "$domain" || echo "  名前解決できず"

echo "== 3. 現在のリゾルバの応答 =="
dig +noall +comments "$domain" | grep -o 'status: [A-Z]*'

echo "== 4. 外部DNSの応答 =="
for ns in 8.8.8.8 1.1.1.1; do
  st=$(dig @"$ns" +noall +comments "$domain" | grep -o 'status: [A-Z]*')
  echo "  $ns -> ${st:-応答なし}"
done

echo "== 5. 権威サーバー(NS)の委任 =="
dig +short NS "$domain" || true

存在しないドメインに対して実行すると、次のようになります。

$ ./dns-check.sh this-domain-does-not-exist-bashdo-test.com
== 1. ローカル設定 (/etc/hosts) ==
  /etc/hosts に該当なし(正常)
== 2. 通常の名前解決 ==
  名前解決できず
== 3. 現在のリゾルバの応答 ==
status: NXDOMAIN
== 4. 外部DNSの応答 ==
  8.8.8.8 -> status: NXDOMAIN
  1.1.1.1 -> status: NXDOMAIN
== 5. 権威サーバー(NS)の委任 ==

正常なドメインなら、同じスクリプトでこう表示されます。

$ ./dns-check.sh bashdo.com
== 1. ローカル設定 (/etc/hosts) ==
  /etc/hosts に該当なし(正常)
== 2. 通常の名前解決 ==
183.90.183.141  bashdo.com
== 3. 現在のリゾルバの応答 ==
status: NOERROR
== 4. 外部DNSの応答 ==
  8.8.8.8 -> status: NOERROR
  1.1.1.1 -> status: NOERROR
== 5. 権威サーバー(NS)の委任 ==
ns1.rakko.zone.
ns2.rakko.zone.

2つを見比べると、5の委任情報が空かどうかで「ドメインとして生きているか」が一目で判断できます。実行にはdnsutils(Debian/Ubuntu)またはbind-utils(RHEL系)が必要です。

sudo apt install dnsutils     # Debian / Ubuntu
sudo dnf install bind-utils   # RHEL / Rocky / AlmaLinux

よくある質問

Q. 特定のサイトだけこのエラーが出ます。原因は?

A. 他のサイトが正常に開けているなら、回線やルーターは問題ありません。まずURLの綴りを確認し、次にdig @8.8.8.8で外部DNSに直接問い合わせてください。外部DNSでNOERRORが返るなら、手元のDNS・広告ブロッカー・VPNのいずれかがそのドメインを遮断しています。外部DNSでもNXDOMAINなら、そのサイト側の問題です。

Q. スマートフォンでもこのエラーが出ます。どうすればいい?

A. Wi-Fiとモバイル通信を切り替えて、片方でだけ発生するか確認してください。片方だけなら、そのネットワークのDNSが原因です。Wi-Fi側で起きる場合は、Wi-Fi設定の詳細からDNSを手動で1.1.1.1などに変更します。両方で発生するなら、URLの誤りかサイト側の問題なので、パソコンから上記のコマンドで確認するのが確実です。

Q. 自分のサーバーにSSHで接続しようとして同じエラーになります

A. ブラウザ表示は出ませんが、ssh: Could not resolve hostnameとして同じNXDOMAINが起きています。~/.ssh/configHostNameに書いたドメインをdig +shortで引いてみてください。IPアドレスが返らなければ、SSHの設定ではなくDNS側の問題です。

Q. NXDOMAINとSERVFAILはどう違いますか?

A. NXDOMAINは「調べた結果、そのドメインは存在しない」という確定的な答えです。一方SERVFAILは「調べようとしたが処理に失敗した」という状態で、DNSSECの検証失敗や上位サーバーの応答不良が原因になります。SERVFAILは別のDNSサーバーに変えると解決することがありますが、NXDOMAINはDNSサーバーを変えても基本的に同じ答えが返ります。

Q. DNSレコードを直したのに、まだNXDOMAINが出ます

A. ネガティブキャッシュが残っている可能性が高いです。SOAレコードの最後の値がその保持秒数なので、dig ドメイン名のAUTHORITY SECTIONで確認してください。待っている間は、dig @権威サーバーで直接問い合わせれば設定が正しいかを検証できます。手元のキャッシュだけはresolvectl flush-caches等でクリアできますが、経路上のキャッシュサーバーは待つしかありません。

Q. digコマンドが見つかりません

A. digdnsutils(Debian/Ubuntu)またはbind-utils(RHEL系)に含まれます。インストールできない環境では、標準で使えるgetent hosts ドメイン名でも名前解決の成否だけは確認できます。ただしDNSの応答コードまでは見えないため、切り分けの精度は落ちます。

まとめ

DNS_PROBE_FINISHED_NXDOMAINは「DNSは動いているが、その名前は存在しない」という限定的なエラーです。闇雲にキャッシュクリアやDNS変更を試すより、digで応答コードを見て、外部DNSと比較する——この2手で原因はほぼ絞り込めます。

  • 手元も外部もNXDOMAIN → URLの綴り、またはサイト側のDNS・ドメイン失効
  • 手元だけNXDOMAIN → /etc/hosts、DNSキャッシュ、DNSサーバー、広告ブロッカー、VPN
  • どちらもNOERROR → ブラウザ側のキャッシュや拡張機能

関連記事

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント