MuntashirAkon/AppManager · error · IOException

Failed to write %,d bytes atomically. Only wrote %,d

Error message

Failed to write %,d bytes atomically. Only wrote  %,d

What it means

FixedLengthBlockOutputStream.writeBlock flushes a full fixed-size block to the underlying channel and requires the write to be atomic: the channel must accept exactly blockSize bytes with none left over. A partial write indicates the underlying channel cannot write atomically in the required block size, so the stream throws rather than risk a corrupt/unaligned block.

Source

Thrown at app/src/main/java/org/apache/commons/compress/utils/FixedLengthBlockOutputStream.java:83

    public FixedLengthBlockOutputStream(final WritableByteChannel out, final int blockSize) {
        this.out = out;
        this.blockSize = blockSize;
        this.buffer = ByteBuffer.allocateDirect(blockSize);
    }

    private void maybeFlush() throws IOException {
        if (!buffer.hasRemaining()) {
            writeBlock();
        }
    }

    private void writeBlock() throws IOException {
        buffer.flip();
        final int i = out.write(buffer);
        final boolean hasRemaining = buffer.hasRemaining();
        if (i != blockSize || hasRemaining) {
            final String msg = String.format(Locale.ROOT, "Failed to write %,d bytes atomically. Only wrote  %,d", blockSize, i);
            throw new IOException(msg);
        }
        buffer.clear();
    }

    @Override
    public void write(final int b) throws IOException {
        if (!isOpen()) {
            throw new ClosedChannelException();
        }
        buffer.put((byte) b);
        maybeFlush();
    }

    @Override
    public void write(final byte[] b, final int offset, final int length) throws IOException {
        if (!isOpen()) {
            throw new ClosedChannelException();
        }

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Use a blocking file/channel sink that supports full-size writes (e.g. FileOutputStream/FileChannel in blocking mode)
  2. Increase the underlying channel's buffer/capacity or drain the consumer side
  3. Catch the IOException and retry the whole block on a channel that supports atomic writes

Example fix

// before
new FixedLengthBlockOutputStream(socketChannel, 512); // partial writes on non-blocking channel
// after
socketChannel.configureBlocking(true);
new FixedLengthBlockOutputStream(socketChannel, 512);
Defensive patterns

Strategy: try-catch

Validate before calling

// verify sink supports blocking atomic writes: if (channel instanceof SocketChannel && !((SocketChannel) channel).isBlocking()) throw new IllegalStateException("need blocking channel");

Try / catch

try { blockStream.write(buffer); blockStream.flushBlock(); } catch (IOException e) { if (e.getMessage().startsWith("Failed to write")) { /* switch to a blocking/direct sink or retry */ } else throw e; }

Prevention

When it happens

Trigger: The underlying channel's write(ByteBuffer) returns fewer bytes than blockSize, or leaves buffer.hasRemaining() true — e.g. writing to a non-blocking channel, a pipe with insufficient capacity, or a channel with a smaller internal buffer.

Common situations: Using a non-blocking SocketChannel as the sink; underlying output streams with small buffers; wrapping channels that do partial writes under load or backpressure.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/8aeb294f03406d95. Report an issue: GitHub.