coredns/coredns · error
RR in %q is not a DNSKEY: %d
Error message
RR in %q is not a DNSKEY: %d
What it means
When reading a DNSSEC key pair, readKeyPair parses the public key file into an RR and verifies it is a DNSKEY record. If dns.NewRR yields a record of any other type (checked via type assertion), the plugin rejects the pair, reporting the actual record type number found in the file.
Source
Thrown at plugin/sign/keys.go:82
return pairs, nil
}
func readKeyPair(public, private string) (Pair, error) {
rk, err := os.Open(filepath.Clean(public))
if err != nil {
return Pair{}, err
}
b, err := io.ReadAll(rk)
if err != nil {
return Pair{}, err
}
dnskey, err := dns.NewRR(string(b))
if err != nil {
return Pair{}, err
}
if _, ok := dnskey.(*dns.DNSKEY); !ok {
return Pair{}, fmt.Errorf("RR in %q is not a DNSKEY: %d", public, dnskey.Header().Rrtype)
}
ksk := dnskey.(*dns.DNSKEY).Flags&(1<<8) == (1<<8) && dnskey.(*dns.DNSKEY).Flags&1 == 1
if !ksk {
return Pair{}, fmt.Errorf("DNSKEY in %q is not a CSK/KSK", public)
}
rp, err := os.Open(filepath.Clean(private))
if err != nil {
return Pair{}, err
}
privkey, err := dnskey.(*dns.DNSKEY).ReadPrivateKey(rp, private)
if err != nil {
return Pair{}, err
}
switch signer := privkey.(type) {
case *ecdsa.PrivateKey:
return Pair{Public: dnskey.(*dns.DNSKEY), KeyTag: dnskey.(*dns.DNSKEY).KeyTag(), Private: signer}, nil
case ed25519.PrivateKey:View on GitHub (pinned to 558c9757a9)
Solutions
- Regenerate or export the correct DNSKEY public key file (e.g. with dnssec-keygen / delv output)
- Confirm the .key file's first record line starts with the zone name and 'IN DNSKEY'
- Re-download the key ensuring you capture the DNSKEY RR, not the DS or other records from the query
- Point the keys directive at the K<zone>+alg+tag.key file produced by dnssec-keygen
Example fix
// before (key file holds a DS record) example.org. 3600 IN DS 12345 13 2 abcdef... // after (key file must hold DNSKEY) example.org. 3600 IN DNSKEY 257 3 13 mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXckHAeF+KkxLbxILfDLUT0nAKFkXe3a0uPcaU==
Defensive patterns
Strategy: validation
Validate before calling
// Verify the public key file contains a DNSKEY RR before use:
b, _ := os.ReadFile(publicKeyPath)
rr, err := dns.NewRR(string(b))
if err != nil || _, ok := rr.(*dns.DNSKEY); !ok {
// not a DNSKEY; regenerate or re-export
} Prevention
- Ensure the .key file exported is a DNSKEY, not DS or other RR types
- Use dnssec-keygen output files directly rather than re-typing key material
- Check file contents start with 'IN DNSKEY' before referencing
- Keep key files separate from zone data files to avoid mixups
When it happens
Trigger: Passing a file that is not a DNSKEY RR — e.g. a DS record, a zone file fragment, an HTML error page from a failed key download, or a DNSKEY response including RRSIG — as the public key argument to the keys directive.
Common situations: Downloading a key from a DNS lookup and saving the wrong RR (DS instead of DNSKEY); using ldns-verify output or a .key file that actually holds a DS; key file mixed up with zone data.
Related errors
- invalid public key format
- directory: not implemented
- DNSKEY in %q is not a CSK/KSK
- unsupported algorithm %s
- no public key found
AI-assisted analysis of coredns/coredns@558c9757a9 (2026-09-06).
Data as JSON: /api/errors/979818ea9adbc50b.
Report an issue: GitHub.