apache/rocketmq · error · AuthenticationException

user can not be null

Error message

user can not be null

What it means

Shared validator used by createUser/updateUser rejected a null User object before touching the metadata store. Indicates a programming error at the call site - the API contract requires an actual User, not null.

Source

Thrown at auth/src/main/java/org/apache/rocketmq/auth/authentication/manager/AuthenticationMetadataManagerImpl.java:194

        } catch (Exception e) {
            this.handleException(e, result);
        }
        return result;
    }

    @Override
    public CompletableFuture<Boolean> isSuperUser(String username) {
        return this.getUser(username).thenApply(user -> {
            if (user == null) {
                throw new AuthenticationException("User:{} is not found", username);
            }
            return user.getUserType() == UserType.SUPER;
        });
    }

    private void validate(User user, boolean isCreate) {
        if (user == null) {
            throw new AuthenticationException("user can not be null");
        }
        if (StringUtils.isBlank(user.getUsername())) {
            throw new AuthenticationException("username can not be blank");
        }
        if (isCreate && StringUtils.isBlank(user.getPassword())) {
            throw new AuthenticationException("password can not be blank");
        }
    }

    private void handleException(Exception e, CompletableFuture<?> result) {
        Throwable throwable = ExceptionUtils.getRealException(e);
        result.completeExceptionally(throwable);
    }

    private AuthenticationMetadataProvider getAuthenticationMetadataProvider() {
        if (authenticationMetadataProvider == null) {
            throw new IllegalStateException("The authenticationMetadataProvider is not configured.");
        }

View on GitHub (pinned to 293f588571)

Solutions

  1. Construct and pass a valid User (username required; password required for create).
  2. Add null/Optional guards at the API boundary so a null never reaches the manager.
  3. If deserialization can yield null, map it to a 400-style validation error instead of calling the manager.

Example fix

// before
authManager.createUser(maybeUser); // maybeUser is null when JSON body absent

// after
User user = Optional.ofNullable(maybeUser).orElseThrow(() -> new IllegalArgumentException("user body required"));
authManager.createUser(user);
Defensive patterns

Strategy: type-guard

Validate before calling

if (user == null) throw new IllegalArgumentException("user payload required");
authManager.createUser(user);

Type guard

boolean isCreatable(User u) { return u != null && u.getUsername() != null && !u.getUsername().trim().isEmpty() && u.getPassword() != null && !u.getPassword().isEmpty(); }

Try / catch

catch (AuthenticationException e) { if message contains "user can not be null" -> fix deserialization/builder at the caller; permanent bug, do not retry. }

Prevention

When it happens

Trigger: Calling createUser(null) or updateUser(null), typically because a mapper/builder returned null (failed parse, missing DTO fields) or a variable was never assigned.

Common situations: RPC layer deserializing an absent body into null; optional-based flows calling .orElse(null); test code exercising edge cases.

Related errors


AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14). Data as JSON: /api/errors/89881ad41737ca10. Report an issue: GitHub.