halo-dev/halo · error · ServerWebInputException
Only support file with extension: {}
Error message
Only support file with extension: {} What it means
Thrown as a ServerWebInputException (HTTP 400) by AvatarUploadRequest.getFile() when the uploaded file's extension is not in ALLOWED_AVATAR_EXTENSIONS. The message interpolates the allowed list (e.g. png, jpg, jpeg, gif, webp) so the caller knows what is accepted.
Source
Thrown at application/src/main/java/run/halo/app/core/endpoint/console/UserEndpoint.java:412
FilePart getFile();
}
public record AvatarUploadRequest(MultiValueMap<String, Part> formData) {
public FilePart getFile() {
Part file = formData.getFirst("file");
if (file == null) {
throw new ServerWebInputException("No file part found in the request");
}
if (!(file instanceof FilePart filePart)) {
throw new ServerWebInputException("Invalid part of file");
}
boolean isNoneExt = Arrays.stream(ALLOWED_AVATAR_EXTENSIONS)
.noneMatch(ext -> filePart.filename().endsWith("." + ext));
if (isNoneExt) {
throw new ServerWebInputException(
"Only support file with extension: " + String.join(", ", ALLOWED_AVATAR_EXTENSIONS));
}
return filePart;
}
}
private Mono<Attachment> uploadAvatar(AvatarUploadRequest uploadRequest) {
var fallbackSetting = environmentFetcher
.fetch(SystemSetting.User.GROUP, SystemSetting.User.class)
.mapNotNull(SystemSetting.User::getAvatarPolicy)
.filter(StringUtils::isNotBlank);
var getAvatarPolicy = environmentFetcher
.fetch(SystemSetting.Attachment.GROUP, SystemSetting.Attachment.class)
.mapNotNull(SystemSetting.Attachment::avatar)
.mapNotNull(UploadOptions::policyName)
.filter(StringUtils::isNotBlank)
.switchIfEmpty(fallbackSetting)
.defaultIfEmpty(DEFAULT_USER_AVATAR_ATTACHMENT_POLICY_NAME);View on GitHub (pinned to d2f5165f9c)
Solutions
- Convert the image to one of the allowed formats (png/jpg/jpeg/gif/webp) before uploading.
- Rename the file to use an allowed extension only if the actual content matches that format.
- If a new format is genuinely required, extend ALLOWED_AVATAR_EXTENSIONS and ensure the storage/attachment policy supports it.
Example fix
// before: upload avatar.bmp // after: convert to png, upload avatar.png
Defensive patterns
Strategy: validation
Validate before calling
// check extension against the allow-list before upload
Set<String> allowed = Set.of("png", "jpg", "jpeg", "gif", "webp");
String ext = name.substring(name.lastIndexOf('.') + 1).toLowerCase(Locale.ROOT);
if (!allowed.contains(ext)) {
showUserError("Allowed: " + allowed);
return;
} Prevention
- Set the file input accept='.png,.jpg,.jpeg,.gif,.webp'.
- Convert/resize images to an allowed format before upload.
When it happens
Trigger: POST to the avatar upload endpoint with a file whose extension is not in the allow-list — e.g. .bmp, .svg, .tif, .heic, or a file with no extension. The check is a simple endsWith so a missing dot also fails.
Common situations: User picks a HEIC photo from a phone; SVG intended as a logo; screenshot saved as .bmp; filename lost its extension during transfer; admin wants a format not in the default allow-list.
Related errors
- No file part found in the request
- Invalid part of file
- The avatar file needs to be smaller than {} MB.
- Required url is missing.
- Policy name must not be blank
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/a74ee347b772a2bb.
Report an issue: GitHub.