次の方法で共有


DNS 更新がタイムアウトになった場合のイベント ID 4016 と 4004

Note

この記事では、Windows Server 2019 以降のバージョンの次の修正プログラムで修正される問題について説明します。

この記事は、ライトウェイト ディレクトリ アクセス プロトコル (LDAP) から Active Directory (AD) への DNS 更新がタイムアウトしたときに、イベント ID 4016 と 4004 がドメイン ネーム システム (DNS) に記録される問題を解決するのに役立ちます。

ドメイン コントローラー (Windows Server 2012 R2 以降のバージョン) でホストされている AD 統合 DNS ゾーンでは、DNS はゾーンを列挙できず、レコードの作成または書き込みに断続的に失敗します。 さらに、イベント ID 4016 と 4004 は DNS イベント ログに記録されます。

  • イベント ID 4016

      LogName:       DNS Server
      Source:        Microsoft-Windows-DNS-Server-Service
      Date:          <DateTime>
      Event ID:      4016
      Task Category:
      Level:         Error
      User:          S-1-5-18
      Computer:      Contoso.com
      Description:
      The DNS server timed out attempting an Active Directory service operation on DC=xx.x,DC=xxx.xx.in-addr.arpa,cn=MicrosoftDNS,DC=ForestDnsZones,DC=xxx,DC=com. Check Active Directory to see that it is functioning properly. The event data contains the error.
    
  • イベント ID 4004

      LogName:       DNS Server
      Source:        Microsoft-Windows-DNS-Server-Service
      Date:          <DateTime>
      Event ID:      4004
      Task Category:
      Level:         Error
      User:          S-1-5-18
      Computer:      Contoso.com
      Description:
      The DNS server was unable to complete directory service enumeration of zone xx.xxx.xx.in-addr.arpa.  This DNS server is configured to use information obtained from Active Directory for this zone and is unable to load the zone without it. Check that the Active Directory is functioning properly and repeat enumeration of the zone. The extended error debug information (which may be empty) is "". The event data contains the error.
    

イベント ID 4016 および 4004 がログに記録された場合、DNS レコードは他のドメイン コントローラーで更新され、ADSI Edit (adsiedit.msc に表示されます。 ただし、レコードを書き込むはずがないし、DNS サーバー サービスが再起動されるまで DNS の更新が停止します。 この期間中は、問題のあるドメイン コントローラーで ADSI Edit を使用して、レコードを同時に作成できます。 これらのレコードは、すべてのドメイン コントローラーにレプリケートされます。つまり、AD が正常に動作していることを意味します。 dns.exe プロセスのメモリ使用量が少ない。 一方、ドメイン コントローラーの CPU とメモリの使用量も少なくなりますが、応答しないままです。

DNS 監査ログ、イベント ログ、パケット キャプチャを確認することで、DNS クエリが迅速に応答した場合でも、サーバー上で DNS の更新が停止します。 さらに、エラー 0x55がログに記録されます。

DNS サーバー サービスを再起動し、Kerberos チケット キャッシュを削除する

この問題を回避するには、Windows PowerShell スクリプトを使用して Kerberos チケット キャッシュを削除した後、DNS サーバー サービスを再起動します。 例については、次のスクリプトを参照してください。

Note

既定の $EventIntervalMinutes 値と $NumberOfEvents 値が最適でない場合があるため、それに応じて値を調整します。

    #NOTE: 
# The following two parameters should be adjusted according to your environment.
# The current values are only defaults and may not be optimal for you.

# How long to wait to ensure the 4016 event occurs consistently (that is, not one-offs)
[int]$EventIntervalMinutes=3

# Number of events within $EventIntervalMinutes to indicate we're in an error state
[int]$NumberOfEvents=10

# Monitor forever
while ($True)
{
	# Detect $NumberOfEvents for 4016 or 4011 occurred in the past $EventIntervalMinutes.
	$EntryType = @("Error","Warning")
	$Events = Get-EventLog -LogName 'DNS Server' -After ((get-date).AddMinutes(-$($EventIntervalMinutes))) -EntryType $EntryType

	[int]$NumEvents=0
	[int]$ErrorStateFound=0
	foreach($Event in $Events)
	{
		 if(($Event.InstanceId -eq "4016") -or ($Event.InstanceId -eq "4011"))
		 {
		   $NumEvents += 1;
		 }
	}

	if($NumEvents -ge $NumberOfEvents)
	{
		$ErrorStateFound=1
		"Detected DNS Event ID 4016 and/or 4011 within the past '$($EventIntervalMinutes)' minutes.  Take mitigation actions."  *>> C:\temp\dnsResetLog.txt

		# Stop DNS
		"`n`nStop DNS at $(Get-Date)" *>> C:\temp\dnsResetLog.txt
		Stop-Service DNS -Force *>> C:\temp\dnsResetLog.txt

		do { Start-Sleep 1 } until ((Get-Service DNS).Status -ne "Running")

		# Purge tickets 
		"`nPurge system tickets at $(Get-Date)" *>> C:\temp\dnsResetLog.txt
		klist purge -li 0x3e7 *>> C:\temp\dnsResetLog.txt

		# Start DNS
		"`nStart DNS at $(Get-Date)" *>> C:\temp\dnsResetLog.txt
		Start-Service DNS *>> C:\temp\dnsResetLog.txt

		# Record DNS Server process details to a file
		Get-Process dns | Select-Object Name, Id, StartTime | Format-List | Out-String *>> C:\temp\dnsResetLog.txt

		"`nEnd at $(Get-Date)" *>> C:\temp\dnsResetLog.txt
	}

	if ($ErrorStateFound)
	{
		# Don't loop again until waiting long enough to ensure no new events after restarting the service
		# Otherwise, we'll keep restarting!
		"`n`Sleeping for ($EventIntervalMinutes+1) minutes" *>> C:\temp\dnsResetLog.txt
		Start-Sleep -seconds (60*($EventIntervalMinutes+1))
		"`n`n Starting new monitoring cycle at $(Get-Date)" *>> C:\temp\dnsResetLog.txt
	}
	else{
		# Give a 1-minute pause before checking again
		Start-Sleep -seconds 60
	}
}