diff --git a/CHANGELOG.md b/CHANGELOG.md
index f381f69df4d41e740d0265873c444548ebfdedf2..00fec361b38f1b33ec5541d11db0873180911547 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,8 @@
 ### Changed
 
 ### Fixed
+- `network::ReconnClient::with_config` constructor now has `pub` visibility,
+  so it's now possible to use it with non-default credentials.
 
 ### Deprecated
 
diff --git a/tarantool/src/lib.rs b/tarantool/src/lib.rs
index 68a8540dd8d3c135d22928f82032e542890b7b19..deb74bb56def57086f4e1918f096fb6672c09a91 100644
--- a/tarantool/src/lib.rs
+++ b/tarantool/src/lib.rs
@@ -7,6 +7,7 @@
 #![allow(clippy::unnecessary_cast)]
 #![allow(clippy::needless_late_init)]
 #![allow(clippy::bool_assert_comparison)]
+#![allow(clippy::field_reassign_with_default)]
 #![allow(rustdoc::redundant_explicit_links)]
 //! Tarantool C API bindings for Rust.
 //! This library contains the following Tarantool API's:
diff --git a/tarantool/src/network/client/mod.rs b/tarantool/src/network/client/mod.rs
index 02c496cb2f339b39b79c76a075150445e04ff92b..229cb4eeace133138670f08a3435da04a8c4eb37 100644
--- a/tarantool/src/network/client/mod.rs
+++ b/tarantool/src/network/client/mod.rs
@@ -69,7 +69,7 @@ pub enum Error {
 
     /// The error is wrapped in a [`Arc`], because some libraries require
     /// error types to implement [`Sync`], which isn't implemented for [`Rc`].
-    #[error("protocol error: {0}")]
+    #[error("{0}")]
     Protocol(Arc<ProtocolError>),
 }
 
@@ -552,7 +552,8 @@ mod tests {
             .await
             .unwrap_err()
             .to_string();
-        assert_eq!(err, "protocol error: service responded with error: Procedure 'unexistent_proc' is not defined");
+        #[rustfmt::skip]
+        assert_eq!(err, "service responded with error: Procedure 'unexistent_proc' is not defined");
     }
 
     #[crate::test(tarantool = "crate")]
diff --git a/tarantool/src/network/client/reconnect.rs b/tarantool/src/network/client/reconnect.rs
index 5334cc15e1d437001d2405aa8dda3b00f0638ad4..fb3081d8c84cf43e2aa3892f032f26eb31a7d504 100644
--- a/tarantool/src/network/client/reconnect.rs
+++ b/tarantool/src/network/client/reconnect.rs
@@ -1,5 +1,6 @@
 use std::rc::Rc;
 
+use super::AsClient;
 use super::Error;
 use crate::fiber::r#async::Mutex;
 use crate::network::protocol;
@@ -13,7 +14,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
 /// when the user finds it necessary.
 /// Can be cloned to utilize the same connection from multiple fibers.
 ///
-/// See [`super::AsClient`] for the full API.
+/// See [`AsClient`] for the full API.
 #[derive(Debug, Clone)]
 pub struct Client {
     client: Rc<Mutex<Option<Result<super::Client, Error>>>>,
@@ -80,7 +81,7 @@ impl Client {
     }
 
     /// Creates a new client but does not yet try to establish connection
-    /// to `url:port`. This will happen at the first call through [`super::AsClient`] methods.
+    /// to `url:port`. This will happen at the first call through [`AsClient`] methods.
     pub fn new(url: String, port: u16) -> Self {
         Self::with_config(url, port, Default::default())
     }
@@ -90,7 +91,7 @@ impl Client {
     ///
     /// Takes explicit `config` in comparison to [`Self::new`]
     /// where default values are used.
-    fn with_config(url: String, port: u16, config: protocol::Config) -> Self {
+    pub fn with_config(url: String, port: u16, config: protocol::Config) -> Self {
         Self {
             client: Default::default(),
             url,
@@ -145,7 +146,6 @@ mod tests {
     use super::*;
     use crate::fiber;
     use crate::fiber::r#async::timeout::IntoTimeout as _;
-    use crate::network::AsClient as _;
     use crate::test::util::listen_port;
     use std::time::Duration;
 
diff --git a/tarantool/src/network/mod.rs b/tarantool/src/network/mod.rs
index 85503b07f7366dd41fe0afb031ef0977c3860f98..c9c8b42854c1e7b78b86e3257a48c410d8508fda 100644
--- a/tarantool/src/network/mod.rs
+++ b/tarantool/src/network/mod.rs
@@ -18,3 +18,35 @@ pub use client::reconnect::Client as ReconnClient;
 #[cfg(feature = "network_client")]
 pub use client::{AsClient, Client, Error};
 pub use protocol::Config;
+
+#[cfg(feature = "internal_test")]
+#[cfg(feature = "network_client")]
+mod tests {
+    use super::*;
+    use crate::test::util::listen_port;
+
+    #[crate::test(tarantool = "crate")]
+    async fn wrong_credentials() {
+        // Wrong user
+        {
+            let mut config = Config::default();
+            config.creds = Some(("no such user".into(), "password".into()));
+            let client = ReconnClient::with_config("localhost".into(), listen_port(), config);
+
+            let err = client.ping().await.unwrap_err();
+            #[rustfmt::skip]
+            assert_eq!(err.to_string(), "service responded with error: User not found or supplied credentials are invalid");
+        }
+
+        // Wrong password
+        {
+            let mut config = Config::default();
+            config.creds = Some(("test_user".into(), "wrong password".into()));
+            let client = ReconnClient::with_config("localhost".into(), listen_port(), config);
+
+            let err = client.ping().await.unwrap_err();
+            #[rustfmt::skip]
+            assert_eq!(err.to_string(), "service responded with error: User not found or supplied credentials are invalid");
+        }
+    }
+}