Introduction

Dynamic DNS (DDNS) automatically updates DNS records when IP addresses change, essential for home networks, remote access, and environments without static IPs. When DDNS updates fail, your hostname points to an old IP and services become unreachable. DDNS involves both client-side software that detects IP changes and server-side systems that accept updates. Troubleshooting requires examining both the update client and the DNS provider's update mechanism.

Symptoms

  • DDNS hostname resolves to old IP address
  • Remote access fails after IP change
  • DDNS client shows update failed or authentication error
  • DNS record not reflecting current IP
  • DDNS service shows last update timestamp is old
  • nslookup/dig returns outdated address
  • Home server or NAS unreachable from internet

Common Causes

  • DDNS client not running or misconfigured
  • Authentication credentials expired or incorrect
  • DDNS provider API/endpoint changed
  • Firewall blocking DDNS update requests
  • Rate limiting by DDNS provider
  • Domain/hostname deleted from DDNS service
  • DDNS provider service outage
  • Update interval too long between checks

Step-by-Step Fix

  1. 1.Verify current IP vs DNS-resolved IP.

```bash # Get your current public IP current_ip=$(curl -s ifconfig.me) echo "Current IP: $current_ip"

# Or alternative services: curl -s ipinfo.io/ip curl -s icanhazip.com curl -s api.ipify.org

# Check what DNS returns for your DDNS hostname dns_ip=$(dig myhost.ddnsprovider.com A +short) echo "DNS IP: $dns_ip"

# Compare if [ "$current_ip" = "$dns_ip" ]; then echo "OK: DNS matches current IP" else echo "PROBLEM: DNS outdated" echo " Current: $current_ip" echo " DNS: $dns_ip" fi ```

  1. 1.Check DDNS client status and logs.

```bash # Check if DDNS client is running # Common DDNS clients:

# ddclient (Linux): systemctl status ddclient journalctl -u ddclient -n 50

# Check ddclient config: cat /etc/ddclient.conf

# inadyn (Linux): systemctl status inadyn cat /etc/inadyn.conf

# Router built-in DDNS: # Check router admin panel -> Dynamic DNS section # Look for status and error messages

# Windows DDNS clients: # Check application logs # Task Manager to verify running

# macOS: # Check LaunchAgents for DDNS scripts # Console.app for logs

# Look for error messages: # - "Update failed" # - "Authentication failed" # - "Bad credentials" # - "Too many requests" # - "Hostname not found" ```

  1. 1.Test DDNS update manually.

```bash # Most DDNS providers have HTTP-based update API

# No-IP example: curl "https://dynupdate.no-ip.com/nic/update?hostname=myhost.ddns.net&myip=NEW_IP" \ -u "username:password"

# DynDNS example: curl "https://members.dyndns.org/nic/update?hostname=myhost.dyndns.org&myip=NEW_IP" \ -u "username:password"

# Cloudflare (via API): curl -X PUT "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records/RECORD_ID" \ -H "Authorization: Bearer API_TOKEN" \ -H "Content-Type: application/json" \ --data '{"type":"A","name":"myhost.example.com","content":"NEW_IP","ttl":300}'

# DuckDNS: curl "https://www.duckdns.org/update?domains=myhost&token=TOKEN&ip=NEW_IP"

# Expected responses: # "good NEW_IP" - Update successful # "nochg NEW_IP" - IP unchanged (already set) # "badauth" - Bad credentials # "nohost" - Hostname doesn't exist # "!donator" - Feature requires paid account # "911" - Server error ```

  1. 1.Verify DDNS credentials are correct.

```bash # Check credentials in DDNS client config

# ddclient config: grep -E "login|password" /etc/ddclient.conf

# Test credentials manually with provider # Example for No-IP: curl -v "https://dynupdate.no-ip.com/nic/update?hostname=test.ddns.net" \ -u "your_username:your_password" 2>&1 | grep -E "< HTTP|good|badauth"

# If response is "badauth": # 1. Check username/email is correct # 2. Verify password (may need DDNS-specific password) # 3. Check if password was changed at provider # 4. Verify hostname exists in your account

# Some providers use separate DDNS passwords: # - Log into DDNS provider website # - Check for DDNS-specific password/token # - Update client config with correct credentials

# For token-based providers (DuckDNS, etc.): # - Verify token is correct # - Token should be long alphanumeric string # - Check token wasn't regenerated ```

  1. 1.Check firewall and network connectivity.

```bash # Test connectivity to DDNS provider:

# No-IP: curl -v https://dynupdate.no-ip.com

# DynDNS: curl -v https://members.dyndns.org

# DuckDNS: curl -v https://www.duckdns.org

# If connection fails: # - Firewall blocking HTTPS # - DNS resolution for provider failing # - Network connectivity issue

# Test DNS resolution for provider: dig dynupdate.no-ip.com A +short

# Check firewall allows HTTPS (443): iptables -L OUTPUT -n | grep 443

# Test from different network if possible # (mobile hotspot, different ISP)

# Router firewall: # Check router doesn't block outbound HTTPS # Some routers have strict outbound filtering ```

  1. 1.Check DDNS provider rate limits.

```bash # DDNS providers limit update frequency

# Common limits: # No-IP: Updates should only happen when IP changes # DynDNS: Max 1 update per minute, penalized for excessive # DuckDNS: 5 minute intervals recommended

# If rate limited: # - Increase update interval in client # - Only update when IP actually changes # - Check provider's documentation for limits

# ddclient interval: # In /etc/ddclient.conf: daemon=300 # Check every 5 minutes

# inadyn interval: # In /etc/inadyn.conf: period = 300 # 5 minutes

# Provider-specific penalties: # - "abuse" status flag # - Temporary update block # - May need to wait hours to clear

# Check provider status page: # Log into DDNS provider -> Account status ```

  1. 1.Verify hostname exists in DDNS provider account.

```bash # Check hostname is active in DDNS provider

# Log into provider website: # - No-IP: Manage Hosts section # - DynDNS: My Services -> Dynamic DNS # - DuckDNS: Main page shows your domains

# Verify: # - Hostname exists in your account # - Hostname is active (not suspended) # - Hostname type matches (A vs AAAA)

# If hostname missing: # - Create new hostname at provider # - Update client config with correct hostname # - Hostnames are case-sensitive in some providers

# ddclient hostname config: # In /etc/ddclient.conf: hostname=myhost.ddns.net

# Check exact hostname: grep hostname /etc/ddclient.conf # Must match exactly what's in provider account ```

  1. 1.Fix common DDNS client configuration errors.

```bash # ddclient common issues:

# Wrong protocol: # Protocol must match provider: protocol=dyndns2 # For DynDNS, No-IP protocol=cloudflare # For Cloudflare

# Check current protocol: grep protocol /etc/ddclient.conf

# Wrong server: server=dynupdate.no-ip.com # No-IP server=members.dyndns.org # DynDNS

# Check server is correct: grep server /etc/ddclient.conf

# Missing daemon mode: daemon=300 # Required for background operation

# Test ddclient manually: ddclient -daemon=0 -verbose -noquiet

# Watch output for errors

# inadyn config example: provider default { hostname = "myhost.ddns.net" username = "myusername" password = "mypassword" provider = "default@no-ip.com" } ```

  1. 1.Implement DDNS monitoring.

```bash # Create monitoring script: #!/bin/bash

HOSTNAME="myhost.ddns.net" LOG_FILE="/var/log/ddns-monitor.log"

current_ip=$(curl -s ifconfig.me) dns_ip=$(dig $HOSTNAME A +short)

timestamp=$(date '+%Y-%m-%d %H:%M:%S')

if [ "$current_ip" != "$dns_ip" ]; then echo "$timestamp: MISMATCH - Current: $current_ip, DNS: $dns_ip" >> $LOG_FILE

# Optionally force update: # systemctl restart ddclient

# Send alert (email, notification) echo "DDNS mismatch detected for $HOSTNAME" | mail -s "DDNS Alert" your@email.com else echo "$timestamp: OK - IP: $current_ip" >> $LOG_FILE fi

# Run periodically via cron: # */5 * * * * /usr/local/bin/ddns-monitor.sh ```

  1. 1.Set up automatic DDNS recovery.

```bash # Configure DDNS client to recover from failures

# ddclient retry settings: # In /etc/ddclient.conf: daemon=300 # Check interval retry=60 # Retry failed updates after 60 seconds timeout=10 # Connection timeout

# systemd service auto-restart: # /etc/systemd/system/ddclient.service: [Service] Restart=always RestartSec=60

# Reload systemd: systemctl daemon-reload systemctl enable ddclient

# Router-based DDNS: # Most routers have retry settings # Check router DDNS configuration page

# For custom scripts with curl: #!/bin/bash HOSTNAME="myhost.ddns.net" TOKEN="your_token" PROVIDER="duckdns"

ip=$(curl -s ifconfig.me) result=$(curl -s "https://www.duckdns.org/update?domains=$HOSTNAME&token=$TOKEN&ip=$ip")

if [[ "$result" != *"OK"* ]]; then echo "Update failed: $result" # Retry logic sleep 60 curl -s "https://www.duckdns.org/update?domains=$HOSTNAME&token=$TOKEN&ip=$ip" fi ```

Verification

Complete DDNS verification:

```bash # 1. Check current vs DNS IP echo "=== IP Comparison ===" current=$(curl -s ifconfig.me) dns=$(dig myhost.ddns.net A +short) echo "Current IP: $current" echo "DNS IP: $dns" [ "$current" = "$dns" ] && echo "OK" || echo "MISMATCH"

# 2. Verify DDNS client running echo -e "\n=== DDNS Client Status ===" systemctl status ddclient 2>/dev/null || \ systemctl status inadyn 2>/dev/null || \ echo "Check router DDNS status"

# 3. Test manual update echo -e "\n=== Manual Update Test ===" curl -s "https://www.duckdns.org/update?domains=myhost&token=TOKEN&ip=$(curl -s ifconfig.me)"

# 4. Check recent logs echo -e "\n=== Recent DDNS Logs ===" journalctl -u ddclient --since "1 hour ago" 2>/dev/null || \ tail -20 /var/log/ddclient.log 2>/dev/null

# 5. Test from external resolver echo -e "\n=== External Resolution ===" dig @8.8.8.8 myhost.ddns.net A +short

# 6. Verify connectivity to provider echo -e "\n=== Provider Connectivity ===" curl -I https://www.duckdns.org 2>&1 | head -5 ```

DDNS Provider Quick Reference

ProviderUpdate URLAuth MethodRate Limit
No-IPdynupdate.no-ip.com/nic/updateusername:passwordDon't abuse
DynDNSmembers.dyndns.org/nic/updateusername:password1/min
DuckDNSduckdns.org/update?domains=...token5 min
Cloudflareapi.cloudflare.com APIAPI token1200/min
Afraid.orgfreedns.afraid.org/dynamic/keyVaries
ChangeIPchangeip.com/nic/updateusername:passwordNormal use

DDNS requires both working client and responsive provider. Regular monitoring ensures you catch issues before remote access becomes impossible.