# How to Fix Java SQL Connection Failed Error
Your Java application fails to connect to the database with one of these errors:
java.sql.SQLException: Connection refused
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at com.myapp.DatabaseManager.connect(DatabaseManager.java:25)Or:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago.Or:
java.sql.SQLException: Access denied for user 'myuser'@'192.168.1.100' (using password: YES)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)Database connection failures can have many causes: network issues, authentication problems, driver configuration, or database server status.
Diagnosis Steps
Step 1: Verify Database Server is Running
```bash # MySQL mysqladmin -h localhost -u root -p status
# PostgreSQL pg_isready -h localhost -p 5432
# SQL Server sqlcmd -S localhost -U sa -P password -Q "SELECT @@VERSION"
# Check if port is listening netstat -an | grep 3306 # MySQL default netstat -an | grep 5432 # PostgreSQL default netstat -an | grep 1433 # SQL Server default ```
Step 2: Test Connection from Command Line
```bash # MySQL mysql -h 192.168.1.100 -P 3306 -u myuser -p
# PostgreSQL psql -h 192.168.1.100 -p 5432 -U myuser -d mydb
# SQL Server sqlcmd -S 192.168.1.100,1433 -U myuser -P password ```
Step 3: Check Network Connectivity
```bash # Test basic connectivity ping 192.168.1.100
# Test specific port telnet 192.168.1.100 3306 # Or using nc nc -zv 192.168.1.100 3306
# Check firewall rules # Linux sudo iptables -L -n | grep 3306 sudo ufw status
# Windows netsh advfirewall firewall show rule name=all | findstr 3306 ```
Step 4: Verify JDBC URL Format
Common URL formats for different databases:
```java // MySQL String url = "jdbc:mysql://host:3306/database?useSSL=false&serverTimezone=UTC";
// PostgreSQL String url = "jdbc:postgresql://host:5432/database";
// SQL Server String url = "jdbc:sqlserver://host:1433;databaseName=database";
// Oracle String url = "jdbc:oracle:thin:@host:1521:SID";
// H2 (embedded) String url = "jdbc:h2:mem:testdb"; ```
Step 5: Test with a Simple Program
```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException;
public class ConnectionTest { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/testdb"; String user = "myuser"; String password = "mypassword";
System.out.println("Loading driver..."); try { Class.forName("com.mysql.cj.jdbc.Driver"); System.out.println("Driver loaded successfully"); } catch (ClassNotFoundException e) { System.err.println("Driver not found: " + e.getMessage()); return; }
System.out.println("Attempting connection..."); try (Connection conn = DriverManager.getConnection(url, user, password)) { System.out.println("Connection successful!"); System.out.println("Connection valid: " + conn.isValid(5)); } catch (SQLException e) { System.err.println("Connection failed!"); System.err.println("SQLState: " + e.getSQLState()); System.err.println("Error Code: " + e.getErrorCode()); System.err.println("Message: " + e.getMessage()); e.printStackTrace(); } } } ```
Solutions
Solution 1: Fix Connection Refused
If you see "Connection refused", the server isn't accepting connections:
```bash # Check if MySQL is running sudo systemctl status mysql
# Start if stopped sudo systemctl start mysql
# Check MySQL bind address cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep bind-address ```
If bind-address is 127.0.0.1, remote connections are blocked. To allow remote connections:
# /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 0.0.0.0Then restart MySQL:
sudo systemctl restart mysqlGrant remote access:
```sql -- Connect as root mysql -u root -p
-- Grant remote access to user CREATE USER 'myuser'@'%' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%'; FLUSH PRIVILEGES;
-- Or for specific IP CREATE USER 'myuser'@'192.168.1.%' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'192.168.1.%'; FLUSH PRIVILEGES; ```
Solution 2: Fix Access Denied
Authentication errors require correct credentials and permissions:
```sql -- Check user exists and host SELECT user, host FROM mysql.user WHERE user = 'myuser';
-- Reset password ALTER USER 'myuser'@'localhost' IDENTIFIED BY 'newpassword'; ALTER USER 'myuser'@'%' IDENTIFIED BY 'newpassword'; FLUSH PRIVILEGES;
-- For MySQL 8+ with caching_sha2_password ALTER USER 'myuser'@'%' IDENTIFIED WITH mysql_native_password BY 'password'; FLUSH PRIVILEGES; ```
Update your Java connection:
```java // For MySQL 8+, specify authentication plugin String url = "jdbc:mysql://localhost:3306/mydb?" + "useSSL=false&" + "serverTimezone=UTC&" + "allowPublicKeyRetrieval=true";
// Use try-with-resources try (Connection conn = DriverManager.getConnection(url, "myuser", "password")) { // Use connection } ```
Solution 3: Add JDBC Driver Dependency
If driver class not found:
Maven: ```xml <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency>
<!-- PostgreSQL --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.7.1</version> </dependency>
<!-- SQL Server --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>12.4.2.jre11</version> </dependency> ```
Gradle: ```groovy // MySQL implementation 'mysql:mysql-connector-java:8.0.33'
// PostgreSQL implementation 'org.postgresql:postgresql:42.7.1'
// SQL Server implementation 'com.microsoft.sqlserver:mssql-jdbc:12.4.2.jre11' ```
Solution 4: Fix SSL/TLS Issues
Modern databases require SSL by default:
javax.net.ssl.SSLHandshakeException: No appropriate protocolOptions in connection URL:
```java // Disable SSL (not recommended for production) String url = "jdbc:mysql://host:3306/db?useSSL=false";
// Use SSL without verification (testing only) String url = "jdbc:mysql://host:3306/db?useSSL=true&verifyServerCertificate=false";
// Proper SSL configuration String url = "jdbc:mysql://host:3306/db?" + "useSSL=true&" + "requireSSL=true&" + "trustCertificateKeyStoreUrl=file:/path/to/truststore.jks&" + "trustCertificateKeyStorePassword=changeit"; ```
Solution 5: Configure Connection Pool
For better reliability, use a connection pool:
HikariCP (Recommended):
```java import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource;
public class DatabasePool { private static HikariDataSource dataSource;
static { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb"); config.setUsername("myuser"); config.setPassword("password"); config.setMaximumPoolSize(10); config.setMinimumIdle(2); config.setConnectionTimeout(30000); config.setIdleTimeout(600000); config.setMaxLifetime(1800000); config.setPoolName("MyAppPool");
// Connection validation query config.setConnectionTestQuery("SELECT 1");
dataSource = new HikariDataSource(config); }
public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } } ```
Maven dependency:
``xml
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.1.0</version>
</dependency>
Solution 6: Handle Connection Timeouts
```java // Add timeout parameters to URL String url = "jdbc:mysql://host:3306/mydb?" + "connectTimeout=10000&" + // 10 seconds to establish connection "socketTimeout=30000&" + // 30 seconds socket timeout "autoReconnect=true&" + // Reconnect on failure "maxReconnects=3"; // Max reconnection attempts
// Configure in connection pool HikariConfig config = new HikariConfig(); config.setConnectionTimeout(10000); // 10 seconds config.setMaxLifetime(1800000); // 30 minutes config.setValidationTimeout(5000); // 5 seconds for validation ```
Solution 7: Fix Firewall and Network Issues
```bash # Linux - Open MySQL port sudo ufw allow 3306/tcp sudo ufw reload
# Or iptables sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT sudo service iptables save
# Check if application can reach database # From application server: telnet db-server-ip 3306 traceroute db-server-ip ```
For Docker containers:
```yaml # docker-compose.yml version: '3' services: app: image: myapp depends_on: - db environment: - DB_HOST=db - DB_PORT=3306 networks: - app-network
db: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=rootpassword - MYSQL_DATABASE=mydb ports: - "3306:3306" networks: - app-network
networks: app-network: ```
Verification
Test the connection with proper error handling:
```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement;
public class VerifyConnection { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC";
try (Connection conn = DriverManager.getConnection(url, "myuser", "password")) { System.out.println("Connected to database!");
// Test query try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT 1")) { if (rs.next()) { System.out.println("Query executed successfully. Result: " + rs.getInt(1)); } }
// Check connection details System.out.println("Database: " + conn.getCatalog()); System.out.println("Auto-commit: " + conn.getAutoCommit()); System.out.println("Valid: " + conn.isValid(5));
} catch (Exception e) { System.err.println("Connection test failed!"); System.err.println("Exception type: " + e.getClass().getName()); System.err.println("Message: " + e.getMessage());
if (e.getCause() != null) { System.err.println("Cause: " + e.getCause().getMessage()); } } } } ```
Quick Reference
| Error | Cause | Solution |
|---|---|---|
| Connection refused | Server not running or not listening | Start server, check bind-address |
| Access denied | Wrong credentials or permissions | Check user exists, reset password |
| Communications link failure | Network/firewall issue | Check firewall, test port connectivity |
| No suitable driver | Driver not in classpath | Add JDBC driver dependency |
| SSL connection error | SSL configuration mismatch | Add SSL parameters or disable for testing |
| Timeout | Slow network or unresponsive server | Increase timeout, check server load |
The diagnostic order: verify server running, test with command-line tools, check credentials, verify JDBC driver, and examine connection URL parameters.