Install & Compatibility
Where this runs
tested against v0.9.26 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.036s · 18.2MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.5s · import 0.030s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
DNSRecord
✓ from dnslib import DNSRecord, DNSHeader, DNSQuestion, QTYPE, RR, A, CNAME, MX, NS, SOA
*
✓ from dnslib import *
✗ from dnslib.dns import *
While `from dnslib import *` is often seen in examples, importing specific classes is generally better practice. The `dnslib.dns` submodule is part of the package structure, but the core classes are typically exposed directly under `dnslib`.
This quickstart demonstrates how to construct a basic DNS A-record query and how to parse a (simulated) DNS response packet. It also shows a minimal example of how to create a reply to a query. Key classes like `DNSRecord`, `DNSQuestion`, and `QTYPE` are used for this.
from dnslib import DNSRecord, DNSHeader, DNSQuestion, QTYPE, RR, A, CNAME
import binascii
# --- Example 1: Creating a simple DNS A query ---
q = DNSRecord(q=DNSQuestion('example.com', QTYPE.A))
print('--- DNS Query (example.com A) ---\n', q)
# Pack the query to wire format
query_packet = q.pack()
# print(f'Wire format: {binascii.hexlify(query_packet).decode()}')
# --- Example 2: Parsing a DNS response (simulated) ---
# Example DNS response packet (e.g., for google.com A record)
# In a real scenario, this would come from a network socket.
# d5ad818000010005000000000377777706676f6f676c6503636f6d0000010001c00c0005000100000005000803777777016cc010c02c0001000100000005000442f95b68c02c0001000100000005000442f95b63c02c0001000100000005000442f95b67c02c0001000100000005000442f95b93
# A simplified, small response for 'test.com' to 1.2.3.4
# Real packets are more complex, this is just for demonstration.
response_hex = b'\x01\x00\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00\x04test\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04\x01\x02\x03\x04'
response_packet = response_hex
# Parse the response packet
try:
r = DNSRecord.parse(response_packet)
print('\n--- Parsed DNS Response (test.com A to 1.2.3.4) ---\n', r)
except Exception as e:
print(f"Error parsing response: {e}")
# --- Example 3: Creating a reply from a query (simplified) ---
q_example = DNSRecord(q=DNSQuestion('host.example.com'))
reply = q_example.reply()
reply.add_answer(RR('host.example.com', QTYPE.A, rdata=A('192.168.1.1')))
print('\n--- Simple DNS Reply ---\n', reply)
Debug
Known issues
deprecatedThe dnslib library is in maintenance mode and no longer undergoes active development. While minor bug fixes may be applied, significant new features or major architectural changes are not expected. Users should factor this into long-term project planning.fixBe aware that new features are unlikely. For active development or a different approach, consider alternatives like `dnspython`.
affects: 0.9.25+
breakingPython 2.7 support has been officially dropped. Version 0.9.24 was the last release to support Python 2.7 and Python <3.7. Later versions require Python 3.7+ (though the 0.9.25 release notes refer to 'Python2 support' in the context of maintenance mode for users reliant on the old API).fixMigrate your application to Python 3.7 or newer. If Python 2.7 support is strictly required, pin the `dnslib` version to `0.9.24` or earlier.
affects: 0.9.25+
breakingSignificant API changes occurred around version 0.9.0 and were further referenced in 0.9.25. Specifically, the 'Bimap' interface for lookups changed, and hostnames are now returned with a trailing dot by default (RFC compliant). Updating from older `dnslib` versions might require code adjustments for these interface changes.fixReview your code for usage of the 'Bimap' interface and hostname parsing/generation logic. Consult the changelog or source for exact API differences if migrating from very old versions.
affects: 0.9.0+, potentially impacting migrations from <0.9.0 and potentially again with 0.9.25+
gotchaThere's a reported issue (Issue #76) where RFC2136 delete UPDATEs are parsed differently between versions. Version 0.9.24 would parse them with `rdata=''`, while 0.9.25+ rejects them, raising an error. This can affect specific DNS update operations.fixIf your application handles RFC2136 delete UPDATEs, test thoroughly after upgrading to 0.9.25+. You may need to adjust your error handling or packet construction/parsing logic for these specific types of updates.
affects: 0.9.25+
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'dnslib'
The 'dnslib' library is not installed in your Python environment.
AttributeError: 'str' object has no attribute 'pack'
This error occurs when an incorrect data type, typically a string, is provided for an RDATA field in a DNS record where a `dnslib` object or bytes-like object is expected for packing into wire format.
fixEnsure that RDATA fields are populated with appropriate `dnslib` objects (e.g., `A(ip)`, `AAAA(ip)`, `MX(preference, label)`, `TXT(data)`) or byte strings where applicable, rather than plain Python strings.
DNSError: Invalid forward lookup: [type]
This error indicates that `dnslib` encountered an unknown or unsupported DNS record type (QTYPE or RTYPE) during processing, which it cannot map using its internal Bimap.
fixCheck the DNS record type you are attempting to process or create. If it's a valid but unsupported type, consider using generic `TYPE(value)` for unsupported RTYPEs, or ensure your `dnslib` version is up-to-date if the type has been recently standardized.
Upgrade
Version history
0.9.26latest on PyPI · released Mar 3, 2025
Audit
Dependencies
No dependency data recorded yet.