ZNC Design Flaws
ZNC requires multiple IRC connections for multiple networks
ZNC requires your IRC client make one connection per network. If a user wants to connect to 10 networks at once (freenode, ircnow, dal, efnet, etc), it requires him to set up 10 independent connections on his IRC client. This is difficult some apps and confusing. ZNC developers have no interest in fixing this.
Login is confusing
If your username is john, your password is secret123, and you want to connect to liberachat, your password field needs to be john/liberachat:secret123. If you want to connect to oftc, your password field needs to be john/oftc:secret123. This is an unintuitive way of changing networks.
ZNC requires too much technical background
Using ZNC requires reading too much documentation in order to use. For example, typing /msg *status help shows a wall of text that only a sysadmin could understand. Jargon like AddTrustedServerFingerprint, ClearAllChannelBuffers, and SetUserBindHost are exposed to users. It would be better if the end-user did not have to read a single page of documentation.
ZNC relies on a web panel
There is no need to bundle a web server with a bouncer. Configuration can be managed without user configuration.
ZNC is written in C++, a language we don't plan to support
ZNC throttles users so it can take hours to connect
The throttling is done poorly -- each connection is attempted and throttled serially, even if the networks being connected to are different. These connections should be done in parallel rather than serially. For example, if you have 30 independent networks to connect to and a 30 second throttling delay, it would take 15 minutes with ZNC, but it should only take 5 seconds with a proper bouncer that connects to all 30 networks simultaneously. There is no need to throttle because they are all unique. On a ZNC server with 100 users, it can take an hour just to connect.
ZNC will disconnect users and throttle if SSL certs are not properly signed
If a server doesn't have a properly signed SSL cert, ZNC will disconnect until the user adds the SSL fingerprint manually. Users often don't understand why. To make matters worse, ZNC insists upon reconnecting and failing indefinitely. This causes connection throttling, slowing everyone from being able to connect. Sysadmins are forced to manually intervene.
ZNC throttles everyone if someone is glined
When someone is GLINEd, ZNC tries to reconnect indefinitely, causing everyone to suffer from connection throttling until a sysadmin manually intervenes.
Upon disconnect, ZNC loses all messages
ZNC does not store any buffers to disk and hence, if crashes or suffers a DDoS attack, will loses all its messages.
IRCv3 adoption causes bugs
IRCv3 adoption has caused documented bugs in older IRC clients. Older versions of mIRC (from around v7.33 to 7.41) are unable to connect because either mIRC or ZNC improperly implement IRCv3 capability negotiation. This bug has also been observed with some other Mac and Android IRC clients. Nothing in the system logs or user clients ever show this error; it just appears to be nonresponsive after IRCv3 capability negotiation.
In another documented bug with ZNC, mode changes don't show up properly on InspIRCd v3.
ZNC can't prefer IPv6 by default
If you try to support both IPv4 and IPv6 simultaneously, ZNC will not prefer IPv6 when available, and there is no way to fix this currently short of a custom patch. If you want to prefer IPv6, you are forced to drop support for IPv4 (you are therefore unable to connect to IPv4-only networks). If you choose to support both IPv4 and IPv6, ZNC usually chooses IPv4 by default, rather than using IPv6 by default. The correct behavior should be IPv6, then fallback to IPv4.
ZNC module relies on commands not supported on all IRCds
The ZNC NickServ module appears to use the /nickserv alias which is not supported on all IRCds (not supported by ngircd). The proper nickserv behavior would be to adapt to each IRC network so that users do not have to memorize the idiosyncrasies of every single network's services. For example, for ngircd, the proper command is /squery nickserv identify <password>; for DALnet, the proper command is /msg firstname.lastname@example.org identify <password>.
ZNC does not offer any easy way to download chat logs
It has a chat log module which stores the chat logs on the server hard disk, but there is no easy way for a user to fetch those logs without ssh access.
ZNC has no way to register instantly upon connection
Ideally, users would be able to register an account instantly upon first connection.
ZNC's Partyline module has been dropped
When users are connected to multiple networks, messages often repeat 2x or more, and sometimes it causes the users to join strange channels without requesting it. This otherwise useful module has been dropped starting v1.8.
ZNC's blockuser module may be buggy
I have not verified this with certainty, but I suspect that if you send a reconnect message to the *controlpanel, it may connect sometimes even if a user is blocked.
ZNC has security issues
ZNC bundles the shell module by default, a module which makes it easy to exploit a 0day to get shell access to the entire server.
Confusing mobile support
A commonly requested feature is to be able to use ZNC for both mobile phone client and PC IRC client. Here's the ZNC wiki explaining how you have multiple clients. This setup is too complex and confusing for normal people to follow.
No fully open source push notifications
ZNC Push Notifications module relies upon closed/non-free software/services. There is no fully open source push notifications for ZNC, an essential feature for a proper mobile IRC client.