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

  1. Seed the test_user table with rows for the expected usernames (admin/user and their roles)
  2. Verify the datasource defaultDataSource points to the database containing the seed data
  3. Check schema/migration scripts run before the permission check executes
  4. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/3ba1b8cd7c4f415e. Report an issue: GitHub.