This might be a duplicate of
PDFBOX-273, although closed, it is clearly not fixed.
PDDocument save (through COSWriter) closes the output, and to make things worse, it closes it twice. Also, it is generally not good practice to close streams, unless you opened them yourself, so I think the streams should just be left alone, and instead the references should be cleared.
The critical code in PDDocument.save(OutputStream output) is:
With COSWriter.close() being:
The problem here is that standardOutput in this case wraps output, thus causing a double close() on output (as FilterOutputStream already closes the stream it wraps).
Double closing itself might not have been a problem, but again FilterOutputStream.close() invokes flush() in its standard implementation, and you cannot flush a closed stream...
Example stack trace:
I tagged the issue with 2.0.4 and 2.0.9 as those are the versions I tested, but I assume the problem is there even before 2.0.4.