DNS was designed to be extensible for new applications via new record types, but the protocol mandates case-insensitivity for domain names. This is useful for hostname lookups, but it could be handled purely on the client side. Building it into the protocol reduces the usefulness of DNS: e.g., looking up the name of the host with address 119.120.121.122 could have use the name z.y.x.w.in-addr.arpa instead of the slightly lengthier and costlier 122.121.120.119.in-addr.arpa.
CNAMEs are unnecessary: two domain names can have the same records without building this referencing into the protocol. CNAMEs complicate the local lookup algorithm for servers. CNAME records might also form a loop, or they might refer to nonexistent names.
A misconfigured or malicious server can respond to a query with some false name server or address records appended to the response. According to the original RFCs, clients should trust these records. Fortunately, modern clients trust records from the cwru.eduname servers only when they belong to names in the cwru.edu domain. BIND adopted a different solution to this problem earlier on - credibility rules, which have their own problems - and has kept those rules even after adopting the simpler rule given above.
NS records contain hostnames, not addresses. As a result, a server may give a referral to another name server without also giving its address. If the name server's name is inside the domain being delegated, the parent is required to provide an address, but in other cases, the child server may be unreachable.
DNS over TCP is slow and prone to denial of service attacks, so it is generally not used except for zone tansfers. DNS over UDP is vulnerable to response spoofing: a client can't tell where the UDP packet came from, so an attacker who can sniff requests can easily send false responses. If the requests aren't sniffable, an attacker can still send false responses, but ey has to guess the query ID and the port the query was sent from. Incorrect guesses incur no penalty for the attacker, however, and BIND uses the same port for all queries.