What I said earlier is correct: once you pass an fd to CreateInsecureChannelFromFd(), you should not close it, because the channel has already taken ownership of it. But it sounds like the question you're actually asking here is about why the channel doesn't automatically reconnect.
When you create a normal channel via CreateChannel(), you get a full client channel that contains all the logic for name resolution, load balancing, and connection management. Since it contains the code to create the fd for each connection, it can automatically create new connections as needed; if the connection to a given address fails, it can try to establish a new connection.
In contrast, when you use CreateInsecureChannelFromFd(), you are creating what is called a "direct" channel. Direct channels do not do name resolution, load balancing, or any connection management; they have just the one fd that you created, and when that fd no longer works, the channel is no longer usable. A direct channel cannot automatically create a new connection when the fd you gave it fails, because it has no idea how you created the connection in the first place -- all it was given is the already-created fd. So if the connection fails, you have to create a whole new channel by creating a new fd and passing it to CreateInsecureChannelFromFd() again.
You say that you tried calling CreateInsecureChannelFromFd() again and that you ran into assertion errors, but I don't know why that would happen. If you can share your code and the assertion error you're seeing, maybe we can help tell you what's wrong.