One of the first things you should do when troubleshooting a problem like this is to enable DNS debug logging. You've got a ton of different options to debug but in my case, I need more information regarding dynamic updates. This is what my configuration looks like on one of my DNS servers.

DNSDebugLogSetting
DNS Debug Logging

When this is enabled, it will begin creating a log file at the file path you specify which looks like this:

DNSDebugLog
DNS Debug Log

The first row of marked out lines is the IP address and the last row is the DNS record it attempted to updated. These were marked out for obvious reasons. Depending on the options you choose this log file can become enormous and isn't in the easiest format to read. What if I want to filter out just a single IP or narrow it down by a certain timeframe? You can't do that with the default log file. This is why I created a PowerShell summary script.

The script below takes this log file and parses it out into a nice CSV file that looks like this:

Output
PowerShellified DNS Debug Log

That looks a whole lot better, right? The script looks through the log file for any errors and parses out the date, IP and the error and places it into a nicely formatted CSV. It also excludes all of the DNS server IPs. For some reason, no matter which option you pick I found that the DNS server IPs themselves kept showing up. I just need to know the client IP address that's having a problem updating it's DNS record.

#requires -Module ActiveDirectory

$dnsServer = '' ## This is the server name as a NETBIOS or FQDN
$OutputFilePath = 'C:\DNSDebugLogSummary.csv' ## The CSV file that will be created

## The log file you specified in the debug logging dialog box
$DnsDebugLogFilePath = "\\$dnsServer\c$\DnsDebugLog.log"

## Find all of the DNS server IPs in the current domain
$DnsServerIPs = ((Get-ADDomain).ReplicaDirectoryServers | Resolve-DnsName).IPAddress
Write-Verbose -Message "Found DNS servers $($DnsServerIPs -join ',')"

## Find all lines in the log file that don't contain the strings 'NOERROR' or are blank.  This
## retrieves only the lines with errors in them.
Select-String -Pattern 'NOERROR|^\s*' -Path $DnsDebugLogFilePath -NotMatch | foreach {
    try {
        ## Find lines containing an IP address
        if ($_.Line -match '\b(?:\d{1,3}\.){3}\d{1,3}\b') {
            Write-Verbose -Message 'Found line with IP address.'
            $IP = $Matches[0]
            ## If the IP isn't a DNS server it must be a client IP
            if ($DnsServerIPs -notcontains $IP) {
                Write-Verbose "Processing IP '$IP'"
                $Split = $_.Line.Split(' ')
                $Date = $Split[0]
                $Time = $Split[1] + $Split[2]
                $Err = [regex]::Match($_.Line, '\[(.*)\]').Groups[1].Value
                [pscustomobject]@{ 'Date' = "$Date $Time"; 'IP' = $IP; 'Error' = $Err }
            }
        }
    } catch {
        Write-Warning $_.Exception.Message
    }
} | Export-Csv -Path $OutputFilePath -Append -NoTypeInformation