DNSSEC10 (dnssec10)

Status: Final

Purpose

  • Verify that signed child-zone nameservers consistently provide NSEC or NSEC3 denial-of-existence material (including signatures and owner/type-shape checks) when querying for apex NSEC and NSEC3PARAM.

Preconditions And Inputs

  • Preconditions:
    • A zone.Zone object is available.
  • Required inputs:
    • Child nameserver name/IP items from methodsv2.GetDelNSNamesAndIPs and methodsv2.GetZoneNSNamesAndIPs.
    • DNSKEY, NSEC, and NSEC3PARAM query responses (DNSSEC enabled).
  • Profile/config knobs that affect behavior:
    • net.ipv4 and net.ipv6: disabled transports are skipped with transport debug tags.
    • resolver.defaults.parallel: per-nameserver parallel execution fanout.

Algorithm And Decision Flow

  1. Emit TEST_CASE_START.
  2. Build child nameserver set from delegation+zone NS items, grouped by IP.
  3. For each unique nameserver IP (parallelized):
    • If transport is disabled, emit IPV4_DISABLED or IPV6_DISABLED for rrtypes DNSKEY, NSEC, and NSEC3PARAM, mark nameserver ignored, and skip.
    • Query DNSKEY (DNSSEC enabled); if response is absent/non-NOERROR/non-AA, mark ignored and skip.
    • If no apex DNSKEY records are returned, classify nameserver as without DNSKEY and skip remaining DS10 checks.
    • Otherwise classify nameserver as with DNSKEY and keep DNSKEY set for signature checks.
  4. Run NSEC query processing:
    • Response-shape failure => NSEC query response error set.
    • Non-empty answer with NSEC records => NSEC-in-answer path (multi-record, apex-owner checks).
    • Non-empty answer without NSEC => erroneous-answer set.
    • Empty answer with NSEC3 in authority => NSEC3-NODATA path (SOA presence/owner checks, NSEC3 owner/type-list checks, signature presence and verification checks).
    • Empty answer with NSEC in authority (no NSEC3) => NSEC-NODATA path for RFC 4470 / RFC 9824 white-lies / minimally covering NSEC / compact denial of existence implementations (SOA presence/owner checks, NSEC count/apex-owner checks, signature presence and verification checks; type-list validation is skipped because the synthesized bitmap intentionally excludes the queried type). Treated as NSEC evidence equivalent to NSEC-in-answer for consistency checks.
  5. Run NSEC3PARAM query processing:
    • Response-shape failure => NSEC3PARAM query response error set.
    • Non-empty answer with NSEC3PARAM => NSEC3PARAM-in-answer path (apex-owner check applied to every NSEC3PARAM RR in the RRset; multiple NSEC3PARAM RRs are permitted to accommodate parameter rollover).
    • Non-empty answer without NSEC3PARAM => erroneous-answer set.
    • Empty answer with NSEC in authority => NSEC-NODATA path (SOA presence/owner checks, NSEC owner/type-list checks, signature presence and verification checks).
  6. During NSEC/NSEC3 signature verification:
    • Track per-keytag conditions: no matching DNSKEY, expired, not-yet-valid, verify error.
    • Track successful verification per nameserver.
    • Track unsupported algorithm situations as DS10_ALGO_NOT_SUPPORTED_BY_ZM.
  7. Aggregate outcomes across nameservers and emit structural consistency tags:
    • DS10_ERR_MULT_*, DS10_INCONSISTENT_*, DS10_MIXED_NSEC_NSEC3, DS10_HAS_NSEC, DS10_HAS_NSEC3.
  8. Emit detailed content/signature tags for NSEC and NSEC3/NSEC3PARAM observations.
  9. Emit DNSSEC-presence summary tags:
    • DS10_ZONE_NO_DNSSEC when only no-DNSKEY responders were observed.
    • DS10_SERVER_NO_DNSSEC when mixed DNSKEY/no-DNSKEY responders were observed.
  10. Emit DS10_EXPECTED_NSEC_NSEC3_MISSING for nameservers with DNSKEY that produced neither expected NSEC nor expected NSEC3 evidence sets.
  11. Emit TEST_CASE_END.

Per-Nameserver DNSKEY Classification (step 3)

stateDiagram-v2
    [*] --> transport
    transport : transport check
    transport --> ignored : disabled
    transport --> queryDNSKEY : enabled
    queryDNSKEY : query DNSKEY
    queryDNSKEY --> ignored : bad response
    queryDNSKEY --> noDNSKEY : no apex DNSKEY
    queryDNSKEY --> withDNSKEY : apex DNSKEY present
    ignored : mark ignored
    noDNSKEY : without DNSKEY
    withDNSKEY : with DNSKEY
    ignored --> [*]
    noDNSKEY --> [*]
    withDNSKEY --> nsecProc
    nsecProc : NSEC and NSEC3PARAM processing
    nsecProc --> [*]

NSEC Query Processing (step 4)

stateDiagram-v2
    [*] --> querying
    querying : query NSEC at apex
    querying --> respErr : shape failure
    querying --> nonEmpty : non-empty answer
    querying --> empty : empty answer
    nonEmpty --> nsecAns : NSEC in answer
    nonEmpty --> errAns : no NSEC in answer
    empty --> nsec3Nodata : NSEC3 in authority
    empty --> nsecNodata : NSEC in authority (no NSEC3)
    empty --> noEvid : neither
    respErr : response error
    nsecAns : NSEC-in-answer path
    errAns : erroneous answer
    nsec3Nodata : NSEC3-NODATA path
    nsecNodata : NSEC-NODATA path (RFC 4470/9824)
    noEvid : no evidence
    respErr --> [*]
    nsecAns --> [*]
    errAns --> [*]
    nsec3Nodata --> [*]
    nsecNodata --> [*]
    noEvid --> [*]

NSEC3PARAM Query Processing (step 5)

stateDiagram-v2
    [*] --> querying
    querying : query NSEC3PARAM at apex
    querying --> respErr : shape failure
    querying --> nonEmpty : non-empty answer
    querying --> empty : empty answer
    nonEmpty --> nsec3pAns : NSEC3PARAM in answer
    nonEmpty --> errAns : no NSEC3PARAM in answer
    empty --> nsecNodata : NSEC in authority
    empty --> noEvid : neither
    respErr : response error
    nsec3pAns : NSEC3PARAM path
    errAns : erroneous answer
    nsecNodata : NSEC-NODATA path
    noEvid : no evidence
    respErr --> [*]
    nsec3pAns --> [*]
    errAns --> [*]
    nsecNodata --> [*]
    noEvid --> [*]

Aggregation and Final Emission (steps 6–11)

stateDiagram-v2
    [*] --> sigTags
    sigTags : signature condition tags
    sigTags --> consTags
    consTags : structural consistency tags
    consTags --> shapeTags
    shapeTags : content and shape tags
    shapeTags --> dkeyCheck
    dkeyCheck : DNSKEY across NSes?
    dkeyCheck --> allDNSKEY : all have DNSKEY
    dkeyCheck --> noDNSKEY : none have DNSKEY
    dkeyCheck --> mixedDNSKEY : mixed
    noDNSKEY --> zoneTag
    zoneTag : DS10_ZONE_NO_DNSSEC
    mixedDNSKEY --> srvTag
    srvTag : DS10_SERVER_NO_DNSSEC
    allDNSKEY --> missing
    zoneTag --> missing
    srvTag --> missing
    missing : DS10_EXPECTED_NSEC_NSEC3_MISSING
    missing --> [*]

Emitted Tags (Possible Set)

TagEmitted when
DS10_ALGO_NOT_SUPPORTED_BY_ZMSignature verification required an unsupported algorithm.
DS10_ERR_MULT_NSECMore than one NSEC record was observed where one was expected.
DS10_ERR_MULT_NSEC3More than one NSEC3 record was observed where one was expected.
DS10_EXPECTED_NSEC_NSEC3_MISSINGNameserver had DNSKEY support but did not provide expected NSEC/NSEC3 evidence.
DS10_HAS_NSECZone behavior is consistently NSEC-only for observed nameservers.
DS10_HAS_NSEC3Zone behavior is consistently NSEC3-only for observed nameservers.
DS10_INCONSISTENT_NSECNSEC evidence is inconsistent across nameservers.
DS10_INCONSISTENT_NSEC3NSEC3 evidence is inconsistent across nameservers.
DS10_INCONSISTENT_NSEC_NSEC3At least one nameserver uses NSEC-only and at least one uses NSEC3-only, with no nameserver exhibiting both simultaneously.
DS10_MIXED_NSEC_NSEC3At least one nameserver shows both NSEC and NSEC3 behavior.
DS10_NSEC3PARAM_GIVES_ERR_ANSWERNSEC3PARAM query had unexpected non-empty answer content.
DS10_NSEC3PARAM_MISMATCHES_APEXNSEC3PARAM owner name did not match zone apex.
DS10_NSEC3PARAM_QUERY_RESPONSE_ERRNSEC3PARAM query had no usable authoritative NOERROR response.
DS10_NSEC3_ERR_TYPE_LISTNSEC3 type bitmap failed mandatory/forbidden checks.
DS10_NSEC3_MISMATCHES_APEXNSEC3 owner hash/name did not match expected apex semantics.
DS10_NSEC3_MISSING_SIGNATURENSEC3 RRset had no matching RRSIG coverage.
DS10_NSEC3_NODATA_MISSING_SOANSEC3 NODATA authority response lacked SOA.
DS10_NSEC3_NODATA_WRONG_SOANSEC3 NODATA authority response had SOA with wrong owner.
DS10_NSEC3_NO_VERIFIED_SIGNATURENSEC3 signatures existed but none verified for affected nameservers.
DS10_NSEC3_RRSIG_EXPIREDNSEC3 RRSIG expired for given keytag.
DS10_NSEC3_RRSIG_NOT_YET_VALIDNSEC3 RRSIG not yet valid for given keytag.
DS10_NSEC3_RRSIG_NO_DNSKEYNSEC3 RRSIG keytag had no matching DNSKEY.
DS10_NSEC3_RRSIG_VERIFY_ERRORNSEC3 RRSIG verification failed for given keytag.
DS10_NSEC_ERR_TYPE_LISTNSEC type bitmap failed mandatory/forbidden checks.
DS10_NSEC_GIVES_ERR_ANSWERNSEC query had unexpected non-empty answer content.
DS10_NSEC_MISMATCHES_APEXNSEC owner name did not match zone apex.
DS10_NSEC_MISSING_SIGNATURENSEC RRset had no matching RRSIG coverage.
DS10_NSEC_NODATA_MISSING_SOANSEC NODATA authority response lacked SOA.
DS10_NSEC_NODATA_WRONG_SOANSEC NODATA authority response had SOA with wrong owner.
DS10_NSEC_NO_VERIFIED_SIGNATURENSEC signatures existed but none verified for affected nameservers.
DS10_NSEC_QUERY_RESPONSE_ERRNSEC query had no usable authoritative NOERROR response.
DS10_NSEC_RRSIG_EXPIREDNSEC RRSIG expired for given keytag.
DS10_NSEC_RRSIG_NOT_YET_VALIDNSEC RRSIG not yet valid for given keytag.
DS10_NSEC_RRSIG_NO_DNSKEYNSEC RRSIG keytag had no matching DNSKEY.
DS10_NSEC_RRSIG_VERIFY_ERRORNSEC RRSIG verification failed for given keytag.
DS10_SERVER_NO_DNSSECAt least one nameserver returned a usable DNSKEY and at least one nameserver returned no usable DNSKEY.
DS10_ZONE_NO_DNSSECNo nameserver returned usable DNSKEY while at least one returned no DNSKEY.
IPV4_DISABLEDIPv4 transport is disabled for a queried nameserver/rrtype.
IPV6_DISABLEDIPv6 transport is disabled for a queried nameserver/rrtype.
TEST_CASE_ENDTestcase completion marker is emitted.
TEST_CASE_STARTTestcase start marker is emitted.

Tag Arguments

TagArgument keyTypeMeaning
DS10_ALGO_NOT_SUPPORTED_BY_ZMkeytag, algo_num, algo_mnemo, addressesint, int, string, stringUnsupported algorithm details and semicolon-delimited nameserver identity/IP list from verification path.
DS10_ERR_MULT_NSECserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_ERR_MULT_NSEC3serversarray<object>Structured nameserver identities ({ns,address} object).
DS10_EXPECTED_NSEC_NSEC3_MISSINGserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_HAS_NSECserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_HAS_NSEC3serversarray<object>Structured nameserver identities ({ns,address} object).
DS10_INCONSISTENT_NSECserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_INCONSISTENT_NSEC3serversarray<object>Structured nameserver identities ({ns,address} object).
DS10_INCONSISTENT_NSEC_NSEC3serversarray<object>Structured nameserver identities ({ns,address} object).
DS10_MIXED_NSEC_NSEC3serversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC3PARAM_GIVES_ERR_ANSWERserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC3PARAM_MISMATCHES_APEXserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC3PARAM_QUERY_RESPONSE_ERRserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC3_ERR_TYPE_LISTserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC3_MISMATCHES_APEXserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC3_MISSING_SIGNATUREserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC3_NODATA_MISSING_SOAserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC3_NODATA_WRONG_SOAdomain, serversstring, stringWrong SOA owner domain and affected nameserver identities (name/ip).
DS10_NSEC3_NO_VERIFIED_SIGNATUREserversarray<object>Structured nameserver identities ({ns,address} object) lacking any verified NSEC3 signature.
DS10_NSEC3_RRSIG_EXPIREDkeytag, serversint, stringKeytag and affected nameserver identities (name/ip).
DS10_NSEC3_RRSIG_NOT_YET_VALIDkeytag, serversint, stringKeytag and affected nameserver identities (name/ip).
DS10_NSEC3_RRSIG_NO_DNSKEYkeytag, serversint, stringKeytag and affected nameserver identities (name/ip).
DS10_NSEC3_RRSIG_VERIFY_ERRORkeytag, serversint, stringKeytag and affected nameserver identities (name/ip).
DS10_NSEC_ERR_TYPE_LISTserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC_GIVES_ERR_ANSWERserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC_MISMATCHES_APEXserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC_MISSING_SIGNATUREserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC_NODATA_MISSING_SOAserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC_NODATA_WRONG_SOAdomain, serversstring, stringWrong SOA owner domain and affected nameserver identities (name/ip).
DS10_NSEC_NO_VERIFIED_SIGNATUREserversarray<object>Structured nameserver identities ({ns,address} object) lacking any verified NSEC signature.
DS10_NSEC_QUERY_RESPONSE_ERRserversarray<object>Structured nameserver identities ({ns,address} object).
DS10_NSEC_RRSIG_EXPIREDkeytag, serversint, stringKeytag and affected nameserver identities (name/ip).
DS10_NSEC_RRSIG_NOT_YET_VALIDkeytag, serversint, stringKeytag and affected nameserver identities (name/ip).
DS10_NSEC_RRSIG_NO_DNSKEYkeytag, serversint, stringKeytag and affected nameserver identities (name/ip).
DS10_NSEC_RRSIG_VERIFY_ERRORkeytag, serversint, stringKeytag and affected nameserver identities (name/ip).
DS10_SERVER_NO_DNSSECserversarray<object>Structured nameserver identities ({ns,address} object) without DNSKEY among mixed responders.
DS10_ZONE_NO_DNSSECserversarray<object>Structured nameserver identities ({ns,address} object) without DNSKEY when zone appears unsigned.
IPV4_DISABLEDns, rrtypestring, stringDisabled nameserver identity (name/ip) and skipped rrtype (DNSKEY, NSEC, NSEC3PARAM).
IPV6_DISABLEDns, rrtypestring, stringDisabled nameserver identity (name/ip) and skipped rrtype (DNSKEY, NSEC, NSEC3PARAM).
TEST_CASE_ENDtestcasestringTestcase display name (DNSSEC10).
TEST_CASE_STARTtestcasestringTestcase display name (DNSSEC10).

Severity Levels Per Tag

TagLevelNotes
DS10_ALGO_NOT_SUPPORTED_BY_ZMNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS10_ERR_MULT_NSECERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_ERR_MULT_NSEC3ERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_EXPECTED_NSEC_NSEC3_MISSINGERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_HAS_NSECINFODefault from share/profile.json (test_levels.DNSSEC).
DS10_HAS_NSEC3INFODefault from share/profile.json (test_levels.DNSSEC).
DS10_INCONSISTENT_NSECERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_INCONSISTENT_NSEC3ERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_INCONSISTENT_NSEC_NSEC3ERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_MIXED_NSEC_NSEC3ERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3PARAM_GIVES_ERR_ANSWERERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3PARAM_MISMATCHES_APEXERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3PARAM_QUERY_RESPONSE_ERRERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_ERR_TYPE_LISTERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_MISMATCHES_APEXERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_MISSING_SIGNATUREERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_NODATA_MISSING_SOAERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_NODATA_WRONG_SOAERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_NO_VERIFIED_SIGNATUREERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_RRSIG_EXPIREDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_RRSIG_NOT_YET_VALIDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_RRSIG_NO_DNSKEYWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC3_RRSIG_VERIFY_ERRORERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_ERR_TYPE_LISTERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_GIVES_ERR_ANSWERERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_MISMATCHES_APEXERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_MISSING_SIGNATUREERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_NODATA_MISSING_SOAERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_NODATA_WRONG_SOAERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_NO_VERIFIED_SIGNATUREERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_QUERY_RESPONSE_ERRERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_RRSIG_EXPIREDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_RRSIG_NOT_YET_VALIDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_RRSIG_NO_DNSKEYWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS10_NSEC_RRSIG_VERIFY_ERRORERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_SERVER_NO_DNSSECERRORDefault from share/profile.json (test_levels.DNSSEC).
DS10_ZONE_NO_DNSSECNOTICEDefault from share/profile.json (test_levels.DNSSEC).
IPV4_DISABLEDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
IPV6_DISABLEDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
TEST_CASE_ENDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
TEST_CASE_STARTDEBUGDefault from share/profile.json (test_levels.DNSSEC).

Differences From Upstream

  • Upstream reference: dnssec10.md
  • Differences (Upstream vs Gonemaster):
    • Upstream: summary for DS10_INCONSISTENT_NSEC_NSEC3 describes two separate lists (ns_list_nsec, ns_list_nsec3). Gonemaster: emits a single combined servers argument.
    • Upstream: most DS10 tags are documented with servers. Gonemaster: DS10_ALGO_NOT_SUPPORTED_BY_ZM uses addresses while other DS10 tags use servers.
    • Upstream: does not explicitly specify testcase boundary and per-query transport debug emissions in this testcase summary. Gonemaster: emits TEST_CASE_START, TEST_CASE_END, IPV4_DISABLED, and IPV6_DISABLED.
    • Upstream: does not handle the case where the NSEC query returns a NODATA response with NSEC in the authority section (RFC 4470 white-lies / minimally covering NSEC / RFC 9824 compact denial of existence, as used by e.g. AWS Route 53, Cloudflare, NS1). This causes a false positive DS10_INCONSISTENT_NSEC for zones using on-line signing. Gonemaster: treats NSEC-in-authority on the NSEC query as NSEC evidence equivalent to NSEC-in-answer for consistency checks, and skips type-list validation on the synthesized NSEC record (whose bitmap intentionally excludes the queried type).
    • DS10_ERR_MULT_NSEC3PARAM is not emitted (the tag has been removed). RFC 5155 does not constrain the cardinality of the apex NSEC3PARAM RRset and a zone may legitimately publish more than one NSEC3PARAM RR during a parameter (salt/iterations) rollover. Gonemaster follows the upstream removal: the apex-owner check (DS10_NSEC3PARAM_MISMATCHES_APEX) is applied to every NSEC3PARAM RR in the answer instead of only the first. Apex-hash verification for the NSEC3 chain itself uses each NSEC3 record’s own salt/iterations, so a multi-chain rollover is already validated correctly without a cardinality check.
  • Potential upstream report:
    • yes – the upstream specification lacks a branch for NSEC-in-authority on the NSEC query, causing false DS10_INCONSISTENT_NSEC for RFC 4470 / RFC 9824 implementations (see zonemaster/zonemaster#1424 ).

Implementation Notes

The following behaviors are implementation choices, not mandated by RFC 4034/4035/5155/4470/9824:

  • Reference time source: RRSIG validity checks use wall-clock time (time.Now().UTC()) as the reference “now”. RFC 4034 requires checking whether signatures are currently valid; using wall-clock time rather than packet timestamps (as dnssec04 does) is an implementation choice appropriate for aggregate multi-nameserver analysis where a single consistent reference point is preferred.
  • Deduplication by IP: The nameserver set is built by IP address; delegation and zone NS entries sharing the same IP are merged. First-seen nameserver identity string (name/ip) is used in output arguments. The protocol does not specify how to handle NS records for the same IP from different sources.
  • servers vs addresses argument name: Most DS10 tags use servers (nameserver identity strings) while DS10_ALGO_NOT_SUPPORTED_BY_ZM uses addresses (raw IPs from the signature verification path). This asymmetry is an implementation-defined output format.
  • RFC 4470 / RFC 9824 white-lies NSEC handling: When the NSEC query returns a NODATA response with NSEC in the authority section (rather than NSEC in the answer section), this is recognized as NSEC evidence from an on-line signing / minimally covering NSEC (RFC 4470) or compact denial of existence (RFC 9824) implementation. RFC 9824 Section 7.2 explicitly permits dynamically generated NSEC records for owner names that don’t exist or are ENTs, relaxing the RFC 4035 constraint. The synthesized NSEC record’s type bitmap intentionally excludes the queried type (NSEC) and may include normally-forbidden types (NSEC3PARAM), so type-list validation is skipped for this record. All other checks (SOA, count, apex owner, signature) are performed normally. For consistency purposes this evidence is treated identically to NSEC-in-answer.

Edge Cases And Limitations

  • Nameserver processing is deduplicated by IP; all DS10 output tags except DS10_ALGO_NOT_SUPPORTED_BY_ZM report servers as nameserver identity strings (name/ip) rather than raw IPs.
  • DS10_NSEC_NO_VERIFIED_SIGNATURE and DS10_NSEC3_NO_VERIFIED_SIGNATURE are suppressed per nameserver when at least one signature verifies for that nameserver.
  • Signature validity checks use testcase wall-clock time (time.Now().UTC()), not packet capture timestamps.