| # | IP | PTR | PTRs | FCrDNS | Scoped | Reason | Notes | |
|---|---|---|---|---|---|---|---|---|
| {{ idx + 1 }} | {{ row.ip }} | {{ row.ptr || '-' }} | {{ row.ptrCount || 0 }} | {{ row.fcrdns }} | {{ row.scoped ? 'Yes' : 'No' }} | {{ row.reason || '-' }} | {{ row.note || '-' }} |
| # | Check | Status | Notes | |
|---|---|---|---|---|
| {{ idx + 1 }} | {{ c.label }} | {{ c.status }} | {{ c.note || '-' }} |
Reverse DNS is the naming path that maps an IP address back to a hostname through a PTR record. That matters because some systems care not only whether an address resolves somewhere, but whether the reverse name exists, whether it points to something sensible, and whether that hostname resolves forward to the same address again. This checker turns those related questions into one result set you can act on.
The package accepts either a literal IP address or a hostname. If you start with a hostname, it first resolves the A and AAAA records behind it, then checks each returned address individually. For every evaluated IP it builds the reverse lookup name, queries PTR answers through DNS-over-HTTPS, and optionally runs forward-confirmed reverse DNS, usually shortened to FCrDNS, by resolving the PTR hostname back to A and AAAA records.
That makes it useful in several operational situations. A mail administrator can confirm whether a sending IP has a consistent reverse name. A platform engineer can audit whether multi-address services all have sane PTR records. A support or security team can explain why a reverse lookup seems incomplete without doing the A, AAAA, PTR, and FCrDNS steps manually for each address.
The result views are deliberately split. The main results table shows the IP, PTR hostname, PTR count, FCrDNS status, scoped-range flag, reason code, and note for each address. The checks tab summarizes higher-level conditions such as whether PTR records exist at all, whether FCrDNS passed, whether strict single-PTR policy held, and whether private or carrier-scoped addresses are present. The JSON export preserves the whole run, including notices, rows, and checks.
The main limit is scope. A clean PTR or FCrDNS result does not prove that the host is trustworthy, reachable, or correctly configured for every service. It only means the reverse and forward naming relationship is consistent under the rules selected in this package. The safest use is to combine it with the operational context that made you ask the question in the first place.
The first decision is whether you are auditing a single address or starting from a hostname. If you already know the exact IP, the result is simpler and faster because the package checks only that address. If you start from a hostname, the package resolves all visible A and AAAA answers first and then checks each resulting IP. That is the better path for services that sit behind multiple addresses or mixed IPv4 and IPv6 records.
The next choice is whether FCrDNS should be enforced. If it is enabled, each PTR hostname has to resolve back to the original IP through forward lookup. That is stricter and more operationally meaningful for many mail and reputation checks. If it is disabled, the package still reports PTR presence, but it marks the FCrDNS check as a warning because one side of the relationship was intentionally skipped.
Strict single PTR is a policy choice rather than a universal law. Some environments expect exactly one PTR hostname per IP and treat anything else as a warning. Others are content as long as one PTR exists and the forward path matches. This package lets you decide which rule to surface, then shows the consequence in both the per-IP rows and the higher-level checks tab.
The scoped-range flag deserves calm interpretation. Private IPv4 space, link-local IPv6 space, loopback, and carrier-scoped ranges often do not have public reverse records at all. The package flags those addresses so a missing PTR is not misread as the same kind of failure you would expect on a public mail or web address. That is a context warning, not a pass.
Use notices and limits intentionally when auditing hostnames. The Max IPs cap prevents very large address sets from turning into an unwieldy audit, while the concurrency and timeout settings shape how aggressively the package queries the resolver. If you are investigating a public service with many addresses, limiting the run can be more useful than blindly checking every answer at once.
The package uses DNS-over-HTTPS endpoints from Cloudflare or Google, or an automatic fallback sequence that tries Cloudflare first and Google second when needed. For each hostname lookup it requests A and AAAA records. For each IP check it builds the corresponding reverse-zone name, either by reversing the dotted IPv4 octets into in-addr.arpa or by expanding the IPv6 address to nibbles and reversing them into ip6.arpa.
PTR processing happens in layers. If the reverse name is invalid, the row fails immediately. If a PTR query returns no usable hostnames, the row becomes a fail when FCrDNS is enabled or a warning when FCrDNS is disabled. If PTR hostnames exist, the package either stops there or continues into forward confirmation, depending on the FCrDNS switch. In the forward-confirmation path, at least one of the PTR hostnames has to resolve back to the original IP to earn a pass.
The result rows carry both a status and a reason code. PASS means PTR exists and, if enabled, forward confirmation succeeded. WARN is used for softer policy issues, such as strict single-PTR mismatch or intentionally disabled FCrDNS. FAIL is used for missing PTR, invalid reverse name, missing forward answers from PTR hostnames, or a forward mismatch where none of the returned A or AAAA records include the original IP.
The checks tab is built from the completed rows rather than from separate network calls. It counts how many IPs had no PTR records, how many passed or failed FCrDNS, whether strict single PTR succeeded when enabled, and whether any addresses belong to private, link-local, or carrier-scoped ranges. That makes the checks tab a synthesized audit summary, while the row table remains the place for per-address troubleshooting.
Operational limits are explicit in the code. Hostname-derived IP lists can be capped with max_ips. Parallelism is bounded between 1 and 16. An extra per-request timeout can be applied in milliseconds. Scoped-range detection covers RFC 1918 private IPv4 space, loopback, link-local addresses, carrier-grade NAT space, IPv6 unique local addresses, and link-local IPv6. All formatting, CSV, DOCX, and JSON exports are generated client-side from the completed result set.
| Condition | Result | Reason code or note |
|---|---|---|
| No valid reverse lookup name can be built | FAIL | invalid_reverse_name |
| No PTR answer and FCrDNS enabled | FAIL | missing_ptr |
| No PTR answer and FCrDNS disabled | WARN | missing_ptr |
| PTR exists, FCrDNS disabled, single-PTR policy satisfied | PASS | fcrdns_disabled |
| PTR exists but forward answers do not include the original IP | FAIL | fcrdns_mismatch |
| PTR hostnames do not resolve to A/AAAA at all | FAIL | ptr_forward_missing |
| Forward confirmation passes but strict single PTR fails | WARN | strict_ptr_mismatch |
| PTR exists and FCrDNS succeeds | PASS | fcrdns_pass |
| Control | Package behavior | Practical use |
|---|---|---|
Resolver |
Uses Cloudflare, Google, or automatic fallback | Lets you compare or stabilize query origin |
FCrDNS |
Requires PTR hostnames to resolve back to the original IP | Turns a simple PTR check into a stronger consistency test |
Strict single PTR |
Warns when an IP has anything other than exactly one PTR hostname | Supports environments with tighter naming policy |
Max IPs |
Limits how many A/AAAA answers are checked from a hostname | Keeps large multi-address audits manageable |
Concurrency |
Controls how many IP checks run in parallel | Balances speed against resolver throttling risk |
Timeout |
Adds an extra abort timer to each request | Prevents slow resolver responses from hanging the audit |
The row table is the authoritative detail view. If an IP fails because no PTR record exists, the reason code tells you that directly. If a PTR record exists but forward confirmation fails, the row tells you whether the problem is “no forward records from the PTR hostname” or “forward records exist but do not include the original IP.” That distinction matters because the fix is different.
The checks tab should be read as an audit summary, not as a second opinion. It is derived from the row results you already saw. A pass there means the batch behaved consistently under the selected rules. A warning there often means policy friction rather than a total break. A fail there means one or more rows showed a hard naming mismatch that the package considers material.
The scoped flag is contextual. A missing PTR on a private or carrier-scoped address is often expected, while the same result on a public service address is usually more significant. The package deliberately surfaces that distinction so that public-name failures and private-range absences are not treated as the same class of problem.
A clean result should not be overread. It means the naming relationship is consistent under the current resolver and settings. It does not prove mail reputation, service health, TLS validity, or application correctness.
An operator checks a public sending IP and sees one PTR hostname with a passing forward-confirmed result. That is the clean case many mail administrators want: one reverse name, one consistent forward path, and no scoped-range caveat.
A hostname resolves to several A and AAAA records. The package expands the hostname first, then checks each IP separately. One address may pass while another lacks PTR or fails forward confirmation, which is much easier to explain in the row table than in a single hostname-level answer.
A private or carrier-scoped address is checked during troubleshooting and comes back without a PTR. The package still flags the absence, but it also marks the address as scoped and adds the note that public reverse DNS is often absent for that class of address. That changes how seriously the missing PTR should be interpreted.
PTR existence only checks whether an IP has a reverse hostname. FCrDNS also checks whether that hostname resolves forward to the same IP.
Because that depends on your policy. The package only warns about it when strict single PTR mode is enabled.
Because the package first resolves the hostname to all visible A and AAAA answers, then audits each resulting IP separately.
No. It means the reverse and forward naming relationship is consistent under the selected rules and resolver.
in-addr.arpa for IPv4 and ip6.arpa for IPv6.