quarkusio/quarkus · error · IllegalStateException
Username '%s' not in the 'test_user' table
Error message
Username '%s' not in the 'test_user' table
What it means
IllegalStateException thrown by JdbcPermissionChecker.hasAdminRole() when the SQL query "select u.role from test_user u where u.username='...'" returns no rows. The authenticated username is valid but not present in the test_user database table, so the role-based permission cannot be resolved.
Source
Thrown at integration-tests/elytron-security-jdbc/src/main/java/io/quarkus/elytron/security/jdbc/it/JdbcPermissionChecker.java:33
@ApplicationScoped
public class JdbcPermissionChecker {
@Inject
AgroalDataSource defaultDataSource;
@Transactional
@PermissionChecker("admin-role-in-db")
boolean hasAdminRole(String usernameHeader) {
String username = switch (usernameHeader) {
case "admin" -> "admin";
case "user" -> "user";
default -> throw new IllegalArgumentException("Invalid username: " + usernameHeader);
};
try (Connection connection = defaultDataSource.getConnection(); Statement stat = connection.createStatement()) {
try (ResultSet roleQuery = stat
.executeQuery("select u.role from test_user u where u.username='" + username + "'")) {
if (!roleQuery.first()) {
throw new IllegalStateException("Username '%s' not in the 'test_user' table".formatted(username));
}
var role = roleQuery.getString(1);
return "admin".equals(role);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Seed the test_user table with rows for the expected usernames (admin/user and their roles)
- Verify the datasource defaultDataSource points to the database containing the seed data
- Check schema/migration scripts run before the permission check executes
- Confirm the username string written into the query matches the row exactly
Example fix
// before: empty table -> no rows
// after (seed)
INSERT INTO test_user (username, role) VALUES ('admin', 'admin');
INSERT INTO test_user (username, role) VALUES ('user', 'user'); Defensive patterns
Strategy: validation
Validate before calling
try (Connection c = defaultDataSource.getConnection();
PreparedStatement ps = c.prepareStatement("select count(*) from test_user where username=?")) {
ps.setString(1, username);
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next() || rs.getInt(1) == 0) {
throw new IllegalStateException("User not seeded: " + username);
}
}
} Type guard
boolean userExists(String username) throws SQLException {
// query test_user for the row; return true only when present
return countByUsername(username) > 0;
} Try / catch
try {
return checkRole(username);
} catch (SQLException e) {
throw new RuntimeException("DB access failed during permission check", e);
} Prevention
- Seed test_user with all usernames the permission checker can resolve
- Use parameterized statements instead of string-concatenated SQL
- Verify the datasource points at the seeded database before running tests
- Add startup validation that required rows exist
When it happens
Trigger: Permission check runs against a database whose test_user table lacks a row for the resolved username — empty/never-seeded DB, or a username whose lookup was just added to the switch but not seeded in the table.
Common situations: Dev/test database not initialized with seed data; schema created by a different migration; DB wiped between runs; inserting into a different datasource than defaultDataSource.
Related errors
- Username and password must be defined when a JDBC URL is pro
- Invalid username: " + usernameHeader
- No producers for required item %s, step builder used: %s
- cycle detection failure report (dynamic CycleBuildException
- Build step '%s' does not produce any build item and thus wil
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/3ba1b8cd7c4f415e.
Report an issue: GitHub.