pentaho/pentaho-kettle · error · IOException

Not a valid input stream!

Error message

Not a valid input stream!

What it means

ZIPCompressionInputStream.close() casts its delegate to ZipInputStream and throws IOException('Not a valid input stream!') when the delegate is null. In practice the guard means the stream was constructed incorrectly or the delegate field was never assigned — the code can only close a real ZipInputStream.

Solutions

  1. Check the IOException thrown at construction time; if the underlying zip file is empty or invalid, fix the source file before reading.
  2. Ensure code never keeps/uses a stream instance whose constructor failed — the delegate will be null.
  3. If writing a subclass, always assign the delegate ZipInputStream before use.
  4. Guard the close call yourself: check the stream opened successfully before closing.

Example fix

// before
ZIPCompressionInputStream in = new ZIPCompressionInputStream(fis); // ctor failed, delegate null
in.close(); // IOException: Not a valid input stream!
// after
ZIPCompressionInputStream in = null;
try {
  in = new ZIPCompressionInputStream(fis);
  ...
} catch (IOException e) {
  // construction failed; do not close
} finally {
  if (in != null) in.close();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (zipFile == null || zipFile.length() == 0) {
  throw new IllegalArgumentException("ZIP source is empty or missing");
}

Try / catch

try (ZIPCompressionInputStream in = new ZIPCompressionInputStream(fis)) { ... } catch (IOException e) { if ("Not a valid input stream!".equals(e.getMessage())) logError("Stream never opened properly"); }

Prevention

When it happens

Trigger: Calling close() on a ZIPCompressionInputStream whose protected 'delegate' field is null — i.e. the object was created without a valid ZipInputStream (bad/empty underlying stream during construction, or a subclass that never set delegate).

Common situations: CompressionInputStreamFactory created a ZIP input on a corrupt/empty zip source causing delegate to be null; custom subclasses overriding setup; closing an already-aborted stream after a failed constructor.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/c0e11ee58050a4ea. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/core/compress/zip/ZIPCompressionInputStream.java:45

  public ZIPCompressionInputStream( InputStream in, CompressionProvider provider ) {
    super( getDelegate( in ), provider );
  }

  protected static ZipInputStream getDelegate( InputStream in ) {
    ZipInputStream delegate;
    if ( in instanceof ZipInputStream ) {
      delegate = (ZipInputStream) in;
    } else {
      delegate = new ZipInputStream( in );
    }
    return delegate;
  }

  @Override
  public void close() throws IOException {
    ZipInputStream zis = (ZipInputStream) delegate;
    if ( zis == null ) {
      throw new IOException( INVALID_INPUT_MSG );
    }
    zis.close();
  }

  @Override
  public int read() throws IOException {
    ZipInputStream zis = (ZipInputStream) delegate;
    if ( zis == null ) {
      throw new IOException( INVALID_INPUT_MSG );
    }
    return zis.read();
  }

  @Override
  public Object nextEntry() throws IOException {
    ZipInputStream zis = (ZipInputStream) delegate;
    if ( zis == null ) {
      throw new IOException( INVALID_INPUT_MSG );

View on GitHub (pinned to f3058517a1)