{"record":{"id":"6627731c86a9d0cf","repo":"aeron-io/aeron","slug":"generic-file-closed-by-interrupt-recording-aborted","errorCode":"GENERIC","errorMessage":"file closed by interrupt, recording aborted","messagePattern":"file closed by interrupt, recording aborted","errorType":"exception","errorClass":"ArchiveException","httpStatus":null,"severity":"critical","filePath":"aeron-archive/src/main/java/io/aeron/archive/RecordingWriter.java","lineNumber":156,"sourceCode":"            if (forceWrites)\n            {\n                recordingFileChannel.force(forceMetadata);\n            }\n\n            final long writeTimeNs = nanoClock.nanoTime() - startNs;\n            recorder.bytesWritten(dataLength);\n            recorder.writeTimeNs(writeTimeNs);\n\n            segmentOffset += length;\n            if (segmentOffset >= segmentLength)\n            {\n                onFileRollOver();\n            }\n        }\n        catch (final ClosedByInterruptException ex)\n        {\n            close();\n            throw new ArchiveException(\"file closed by interrupt, recording aborted\", ex, ArchiveException.GENERIC);\n        }\n        catch (final IOException ex)\n        {\n            close();\n            checkErrorType(ex, length);\n        }\n        catch (final Exception ex)\n        {\n            close();\n            LangUtil.rethrowUnchecked(ex);\n        }\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    public void close()","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/RecordingWriter.java#L138-L174","documentation":"RecordingWriter.onBlock writes received blocks of recorded data to the segment file. If the write is interrupted via ClosedByInterruptException (the thread's interrupt flag was set during file I/O, typically because the task/future was cancelled), the writer closes itself and rethrows an ArchiveException with GENERIC error code, aborting the recording.","triggerScenarios":"The thread executing onBlock (recorder agent) is interrupted while writing to the recording segment file — e.g. the recording was cancelled, the archive agent's executor shut down with interrupt, or application code interrupts the owning thread during FileChannel write/force operations.","commonSituations":"Calling RecordingSubscriptionDescriptor.stopRecording / cancelling the archive client session, which interrupts the recorder; ExecutorService.shutdownNow() during application shutdown while a recording is active; timeout-based cancellation of the recording task.","solutions":["This indicates the recording was deliberately aborted: stop the recording cleanly with stopRecording rather than interrupting the recorder thread.","Check who interrupts the thread (Future.cancel(true), shutdownNow) and use non-interrupting cancellation for the recording lifecycle.","Treat the writer as closed after this exception — create a new recording if data capture must continue.","During shutdown, let in-flight recordings finish or explicitly close them before shutting down the executor."],"exampleFix":"// before\nexecutor.shutdownNow(); // interrupts recorder mid-write\n// after\nrecordingSubscription.cancel(); // stop recording cleanly\nexecutor.shutdown();","handlingStrategy":"try-catch","validationCode":"// avoid interrupting the recorder thread: check before cancelling\nif (!Thread.currentThread().isInterrupted()) { recordingSubscription.cancel(); }","typeGuard":null,"tryCatchPattern":"try {\n    writer.onBlock(buffer, offset, length, sessionId, termId);\n} catch (ArchiveException e) {\n    if (e.errorCode() == ArchiveException.GENERIC\n        && e.getMessage().contains(\"file closed by interrupt\")) {\n        log.warn(\"recording aborted by interrupt; recorder is closed\");\n        // do not reuse the writer; start a new recording if needed\n    }\n}","preventionTips":["Stop recordings with stopRecording/cancel rather than thread interrupts.","Avoid Future.cancel(true) and shutdownNow() on threads performing archive writes.","Complete or explicitly close active recordings before executor shutdown.","Keep interrupt-flag hygiene: clear/inspect interrupt status in code owning recorder threads."],"tags":["interrupt","file-io","archive","recording-aborted"],"backgroundTag":"thread-interrupted","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}