pentaho/pentaho-kettle · error · IOException

could not connect to pipedInputStream

Error message

could not connect to pipedInputStream

What it means

Thrown in the S3CommonPipedOutputStream constructor when PipedInputStream.connect() fails. This is marked FATAL/unexpected: a fresh PipedInputStream connected to itself in the same thread should never throw, so this signals a JVM-level internal problem.

Solutions

  1. Never reuse or share the PipedInputStream created inside this constructor
  2. Construct a new S3CommonPipedOutputStream per upload instead of reconnecting an existing one
  3. Inspect the wrapped IOException; if it says 'Already connected', find the code path reusing the stream
  4. Check for custom subclasses overriding stream state
Defensive patterns

Strategy: try-catch

Try / catch

try {
  S3CommonPipedOutputStream out = new S3CommonPipedOutputStream( bucketId, key, fileSystem );
} catch ( IOException e ) {
  throw new IllegalStateException( "pipewire init failed (should be impossible): " + e.getMessage(), e );
}

Prevention

When it happens

Trigger: Constructing S3CommonPipedOutputStream; PipedInputStream.connect(this) throws IOException (only possible if the pipe is already connected to another reader, i.e. an internal invariant violation).

Common situations: Extremely rare; could appear if code is refactored to reuse/reconnect a shared piped stream, or with custom subclassing that pre-connects the stream.

Related errors


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

Appendix: source

Thrown at plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonPipedOutputStream.java:80

  private String bucketId;
  private String key;
  /**
   * AWS Multipart part size.
   */
  private int partSize;

  public S3CommonPipedOutputStream( S3CommonFileSystem fileSystem, String bucketId, String key ) throws IOException {
    this( fileSystem, bucketId, key, DEFAULT_PART_SIZE );
  }

  public S3CommonPipedOutputStream( S3CommonFileSystem fileSystem, String bucketId, String key, int partSize ) throws IOException {
    this.pipedInputStream = new PipedInputStream();

    try {
      this.pipedInputStream.connect( this );
    } catch ( IOException e ) {
      // FATAL, unexpected
      throw new IOException( "could not connect to pipedInputStream", e );
    }

    this.s3AsyncTransferRunner = new S3AsyncTransferRunner();
    this.bucketId = bucketId;
    this.key = key;
    this.fileSystem = fileSystem;
    this.partSize = partSize;
  }

  private void initializeWrite() {
    if ( !initialized ) {
      initialized = true;
      result = this.executor.submit( s3AsyncTransferRunner );
    }
  }

  public boolean isBlockedUntilDone() {
    return blockedUntilDone;

View on GitHub (pinned to f3058517a1)