Errors are private, library-specific, and you are supposed to convert them to your domain errors when handling them. The API is telling you this by not letting you create instances of them.
The standard library in particular tends to default to exposing at little surface area as possible, because once something is on stable, the exposed parts must be supported forever, and they might be forced to create some new types and deprecate the old instead of iterating internal details.
Errors in Rust are basically human-meaningful manual implementations of backtraces. The best practice consists of special-purpose error types for each logical unit of code (which can be as small as single functions, or at worst as large as a library). If it's possible to instantiate foreign errors in your own code in entirely unrelated context, they can't serve the purpose of backtraces, can they? Getting some error type wouldn't give you any information on where the error originates from.
This is marred by the fact that you can still directly propagate foreign error types from your functions, without converting them into your domain-specific errors. Ideally you should do it only when your own function doesn't have any more meaningful reason for those errors.