quarkusio/quarkus · error · IllegalArgumentException
Invalid username: " + usernameHeader
Error message
Invalid username: " + usernameHeader
What it means
IllegalArgumentException thrown by JdbcPermissionChecker.hasAdminRole(), a @PermissionChecker used for @PermissionAction-based authorization. The username header supplied to the permission check is not one of the recognized values ("admin" or "user"), so the switch's default arm rejects it. It guards against arbitrary/unexpected header values reaching the SQL lookup.
Source
Thrown at integration-tests/elytron-security-jdbc/src/main/java/io/quarkus/elytron/security/jdbc/it/JdbcPermissionChecker.java:27
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import io.agroal.api.AgroalDataSource;
import io.quarkus.security.PermissionChecker;
@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
- Send the expected username header value ("admin" or "user") with the request
- Extend the switch to handle additional valid usernames if the test adds users
- Null-check/normalize (trim) the header value before the switch
- Check header name casing and any proxy stripping of custom headers
Example fix
// before
default -> throw new IllegalArgumentException("Invalid username: " + usernameHeader);
// after
if (usernameHeader == null) {
throw new IllegalArgumentException("Missing username header");
}
String normalized = usernameHeader.trim();
default -> throw new IllegalArgumentException("Invalid username: " + normalized); Defensive patterns
Strategy: validation
Validate before calling
if (usernameHeader == null || !(usernameHeader.equals("admin") || usernameHeader.equals("user"))) {
throw new BadRequestException("username header must be 'admin' or 'user'");
} Type guard
boolean isValidUsername(String u) {
return "admin".equals(u) || "user".equals(u);
} Try / catch
try {
return checkPermission(header);
} catch (IllegalArgumentException e) {
throw new ForbiddenException(e.getMessage());
} Prevention
- Validate/normalize header values before the switch
- Keep the allowlist of accepted usernames in one constant
- Cover the default arm with a unit test using an unexpected username
When it happens
Trigger: Request supplies a usernameHeader value other than "admin" or "user" (or no header at all, making it null), causing the switch default to throw before the JDBC query runs.
Common situations: Test client forgetting to set the username header; header spelled differently or with whitespace/case mismatch; new expected users not added to the switch; header consumed by a proxy.
Related errors
- Path is not below the application root: <file>
- Symbolic links are not allowed in remote-dev paths: <file>
- No workspace path provided
- '..' cannot be used in resource paths, but got
- Username '%s' not in the 'test_user' table
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/ecf3b68c26542c31.
Report an issue: GitHub.