halo-dev/halo · error · ServerWebInputException

The avatar file needs to be smaller than {} MB.

Error message

The avatar file needs to be smaller than {} MB.

What it means

Thrown as a ServerWebInputException (HTTP 400) inside maxSizeCheck while streaming the avatar's DataBuffer content. An AtomicInteger accumulates readable bytes; once the running total exceeds MAX_AVATAR_FILE_SIZE, the stream is aborted with a message naming the megabyte limit. The check is per-buffer, so the upload is rejected mid-stream rather than buffered fully.

Source

Thrown at application/src/main/java/run/halo/app/core/endpoint/console/UserEndpoint.java:448

                .defaultIfEmpty(DEFAULT_USER_AVATAR_ATTACHMENT_POLICY_NAME);
        return getAvatarPolicy.flatMap(avatarPolicy -> {
            FilePart filePart = uploadRequest.getFile();
            var ext = Files.getFileExtension(filePart.filename());
            return attachmentService.upload(
                    avatarPolicy,
                    USER_AVATAR_GROUP_NAME,
                    UUID.randomUUID() + "." + ext,
                    maxSizeCheck(filePart.content()),
                    filePart.headers().getContentType());
        });
    }

    private Flux<DataBuffer> maxSizeCheck(Flux<DataBuffer> content) {
        var lenRef = new AtomicInteger(0);
        return content.doOnNext(dataBuffer -> {
            int len = lenRef.accumulateAndGet(dataBuffer.readableByteCount(), Integer::sum);
            if (len > MAX_AVATAR_FILE_SIZE.toBytes()) {
                throw new ServerWebInputException(
                        "The avatar file needs to be smaller than " + MAX_AVATAR_FILE_SIZE.toMegabytes() + " MB.");
            }
        });
    }

    private Mono<ServerResponse> createUser(ServerRequest request) {
        return request.bodyToMono(CreateUserRequest.class)
                .doOnNext(createUserRequest -> {
                    if (StringUtils.isBlank(createUserRequest.name())) {
                        throw new ServerWebInputException("Name is required");
                    }
                    if (StringUtils.isBlank(createUserRequest.email())) {
                        throw new ServerWebInputException("Email is required");
                    }
                })
                .flatMap(userRequest -> {
                    User newUser = CreateUserRequest.from(userRequest);
                    var encryptedPwd = userService.encryptPassword(userRequest.password());

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Compress or resize the image so its byte size is under the configured MAX_AVATAR_FILE_SIZE before uploading.
  2. Add a client-side size guard (check File.size) and reject oversized files before the request.
  3. If the policy allows, raise MAX_AVATAR_FILE_SIZE in configuration to fit expected avatars.

Example fix

// before: upload a 12 MB photo with a 2 MB cap
// after: resize to <=256px and compress before upload so size < cap
Defensive patterns

Strategy: validation

Validate before calling

// guard on byte size before uploading
long MAX = MAX_AVATAR_FILE_SIZE.toBytes(); // mirror server cap
if (selectedFile.length() > MAX) {
    showUserError("File must be smaller than " + (MAX / 1_000_000) + " MB");
    return;
}

Prevention

When it happens

Trigger: POST to the avatar upload endpoint with a file whose total content size exceeds MAX_AVATAR_FILE_SIZE (the configured megabyte cap). The exception fires as soon as the cumulative bytes cross the threshold.

Common situations: User uploads a high-res phone photo directly; animated GIF oversized; default size cap too small for the organization's needs; frontend lacks a pre-upload size check.

Related errors


AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14). Data as JSON: /api/errors/642b0458fecf0365. Report an issue: GitHub.