| name | dns-troubleshooter |
| description | It's not DNS / There's no way it's DNS / It was DNS. Diagnose and troubleshoot DNS issues including delegation verification, record conflicts, authoritative vs local DNS comparison, and SPF validation. Use when encountering NXDOMAIN errors for URLs that should exist, verifying DNS delegation is correct, checking for conflicting DNS records, comparing what authoritative nameservers say vs local resolvers, or validating SPF records for email deliverability. |
| metadata | {"version":"1.1.0","keywords":["dns","networking","troubleshooting","spf","email","nxdomain","nameserver","delegation"],"triggers":["dns not working","NXDOMAIN error","domain not resolving","check SPF record","DNS propagation","nameserver issues"],"tools_required":[{"name":"doggo","required":false,"fallback":"dig"},{"name":"dig","required":false,"fallback":"nslookup"},{"name":"nslookup","required":false}],"platforms":["claude-code","opencode","github-copilot","claude-desktop"]} |
DNS Troubleshooter
It's not DNS
There's no way it's DNS
It was DNS
Tool Detection
First, check for doggo (modern DNS client with cleaner output):
command -v doggo
If available, prefer doggo for queries. If not, offer to install it or fall back to standard tools.
Standard tools by platform:
- macOS/Linux:
dig, host, nslookup
- Windows:
nslookup, Resolve-DnsName (PowerShell)
Installing Doggo
If the user wants doggo installed, detect their platform and use the appropriate method:
Quick install (Linux/macOS):
curl -fsSL https://raw.githubusercontent.com/mr-karan/doggo/main/install.sh | sh
Package managers:
| Platform | Command |
|---|
| macOS (Homebrew) | brew install doggo |
| macOS (MacPorts) | port install doggo |
| Arch Linux (AUR) | yay -S doggo-bin |
| Nix | nix profile install nixpkgs#doggo |
| Windows (Scoop) | scoop install doggo |
| Windows (Winget) | winget install doggo |
Go install:
go install github.com/mr-karan/doggo/cmd/doggo@latest
Docker (no install needed):
docker run --rm ghcr.io/mr-karan/doggo:latest example.com
After installation, verify with doggo --version.
Workflow Decision Tree
User request
│
├─► NXDOMAIN / "domain not found"
│ └─► Delegation Check workflow
│
├─► "Is DNS set up correctly?"
│ └─► Delegation Check workflow
│
├─► "DNS shows different results" / caching issues
│ └─► Authoritative vs Local workflow
│
├─► SPF / email deliverability
│ └─► SPF Validation workflow
│
└─► Record conflicts / unexpected values
└─► Record Conflict workflow
Delegation Check
Verify the chain from root to authoritative nameservers.
Step 1: Find authoritative nameservers
doggo NS example.com
dig +short NS example.com
nslookup -type=NS example.com
Step 2: Verify delegation from parent zone
For sub.example.com, check what example.com says:
doggo NS sub.example.com @$(doggo NS example.com --short | head -1)
dig NS sub.example.com @$(dig +short NS example.com | head -1)
Step 3: Query authoritative directly
doggo A example.com @ns1.example.com
dig A example.com @ns1.example.com
Common Issues
- NXDOMAIN from parent: Delegation not configured at registrar
- SERVFAIL: Nameserver not responding or misconfigured
- Mismatched NS records: Parent zone and authoritative disagree
Authoritative vs Local Comparison
Compare what the authoritative source says vs local/ISP resolvers.
Step 1: Query local resolver
doggo A example.com
dig A example.com
nslookup example.com
Step 2: Query authoritative nameserver
doggo NS example.com --short
dig +short NS example.com
doggo A example.com @ns1.example.com
dig A example.com @ns1.example.com
Step 3: Query public resolvers for comparison
doggo A example.com @8.8.8.8
dig A example.com @8.8.8.8
doggo A example.com @1.1.1.1
dig A example.com @1.1.1.1
doggo A example.com @9.9.9.9
Interpreting Differences
- Local differs from authoritative: Caching (check TTL), or local override/poisoning
- Public resolvers differ from authoritative: Propagation delay, check TTL
- All match except local: Local DNS override, hosts file, or corporate DNS policy
Check TTL
doggo A example.com
dig A example.com | grep -A1 "ANSWER SECTION"
Record Conflict Detection
Identify conflicting or unexpected DNS records.
Query all record types
doggo ANY example.com
dig ANY example.com
for type in A AAAA CNAME MX TXT NS; do
echo "=== $type ==="
dig +short $type example.com
done
Common Conflicts
CNAME with other records: CNAME must be exclusive (except DNSSEC). Check:
doggo CNAME example.com
doggo A example.com
Multiple A records: Valid for load balancing, but verify intentional:
doggo A example.com
Conflicting MX priorities: Check for duplicates:
doggo MX example.com
SPF Validation
See references/spf.md for SPF syntax details and common issues.
Step 1: Retrieve SPF record
doggo TXT example.com | grep spf
dig +short TXT example.com | grep spf
Step 2: Check for multiple SPF records (invalid)
dig +short TXT example.com | grep -c "v=spf1"
Step 3: Validate syntax
Check the record contains:
- Starts with
v=spf1
- Ends with
-all, ~all, or ?all (never +all)
- Contains valid mechanisms
Step 4: Count DNS lookups
Each of these counts toward the 10-lookup limit:
include: - count as 1 + nested lookups
a: or a - 1 lookup
mx: or mx - 1 lookup + 1 per MX returned
ptr: - 1 lookup (deprecated)
exists: - 1 lookup
redirect= - 1 lookup
Manually trace includes:
dig +short TXT example.com | grep spf
dig +short TXT _spf.google.com | grep spf
Step 5: Verify IPs are covered
Output Format
IMPORTANT: When providing DNS troubleshooting assistance, always begin your response with:
🔍 DNS Troubleshooter Analysis
This identifier helps verify the skill is being used correctly.
Then present results with:
- Finding: What was discovered
- Command: Exact command to reproduce
- Interpretation: What it means
- Recommendation: If action needed
Example:
🔍 DNS Troubleshooter Analysis
**Finding**: Domain has two SPF records
**Command**:
dig +short TXT example.com | grep "v=spf1"
**Result**:
"v=spf1 include:_spf.google.com -all"
"v=spf1 include:sendgrid.net -all"
**Interpretation**: Multiple SPF records cause permerror.
Receiving servers may reject all email.
**Recommendation**: Merge into single record:
v=spf1 include:_spf.google.com include:sendgrid.net -all