{"record":{"id":"e4d2011ef887a1b5","repo":"quarkusio/quarkus","slug":"returning-an-asyncfile-is-not-supported-with-write","errorCode":null,"errorMessage":"Returning an AsyncFile is not supported with WriterInterceptors","messagePattern":"Returning an AsyncFile is not supported with WriterInterceptors","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/serializers/ServerMutinyAsyncFileMessageBodyWriter.java","lineNumber":81,"sourceCode":"        });\n\n        file.endHandler(new Runnable() {\n            @Override\n            public void run() {\n                // we don't need to wait for the file to be closed, we just need to make sure it does get closed\n                //noinspection ResultOfMethodCallIgnored\n                file.close().subscribeAsCompletionStage();\n                response.end();\n                // Not sure if I need to resume, actually\n                ctx.resume();\n            }\n        });\n    }\n\n    @Override\n    public void writeTo(AsyncFile asyncFile, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,\n            MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {\n        throw new UnsupportedOperationException(\"Returning an AsyncFile is not supported with WriterInterceptors\");\n    }\n}\n","sourceCodeStart":63,"sourceCodeEnd":84,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/vertx/src/main/java/org/jboss/resteasy/reactive/server/vertx/serializers/ServerMutinyAsyncFileMessageBodyWriter.java#L63-L84","documentation":"ServerMutinyAsyncFileMessageBodyWriter.writeTo() unconditionally throws UnsupportedOperationException: returning a Vert.x AsyncFile as a Jakarta REST entity is only supported when it can be written directly (no WriterInterceptors apply). When WriterInterceptors are present, the writer must use the entity OutputStream, which AsyncFile streaming cannot support, so it fails fast.","triggerScenarios":"A Jakarta REST resource method returns a Vert.x AsyncFile (or Mutiny AsyncFile) entity while WriterInterceptors are registered (e.g. custom @WriterInterceptor, some compression/ logging interceptors), causing the interceptor-aware writeTo path to be used.","commonSituations":"Serving files via AsyncFile after adding a writer interceptor (e.g. for logging or encryption); upgrading Quarkus where interceptors newly apply to the AsyncFile writer path.","solutions":["Remove or disable the WriterInterceptor for AsyncFile responses (target it to other types via @InterceptorBinding/accepted media types).","Return the file content differently: InputStream/File/StreamingOutput instead of AsyncFile when interceptors are needed.","Write the file bytes into the provided OutputStream manually inside the endpoint if interceptor processing is required."],"exampleFix":"// before\n@GET public AsyncFile download() { return fileSystem.open(...); } // with WriterInterceptor -> throws\n// after\n@GET public File download() { return new File(path); } // interceptor-compatible","handlingStrategy":"validation","validationCode":"// before returning AsyncFile, check no writer interceptors will apply\nboolean hasWriterInterceptors = !interceptorRegistry.getWriterInterceptors(asyncFileType, mediaType).isEmpty();\nif (hasWriterInterceptors) return toFileOrInputStream(asyncFile);","typeGuard":"boolean canReturnAsyncFile(Object entity, boolean writerInterceptorsPresent) {\n    return entity instanceof io.vertx.mutiny.core.file.AsyncFile && !writerInterceptorsPresent;\n}","tryCatchPattern":"try {\n    return asyncFile;\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"AsyncFile is not supported\")) {\n        return readFileAsInputStream(path); // fallback\n    }\n    throw e;\n}","preventionTips":["Check registered WriterInterceptors before returning AsyncFile entities.","Scope interceptors to specific types/media types so they don't hit AsyncFile.","Prefer File/InputStream/StreamingOutput entities when interceptors are needed."],"tags":["asyncfile","writer-interceptor","unsupported-operation","rest"],"backgroundTag":"unsupported-operation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}