{"record":{"id":"98a928afdb8eeb74","repo":"pentaho/pentaho-kettle","slug":"could-not-read-file","errorCode":null,"errorMessage":"Could not read file ","messagePattern":"Could not read file ","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/s3-vfs/core/src/main/java/org/pentaho/amazon/s3/provider/S3Provider.java","lineNumber":200,"sourceCode":"    } finally {\n      Thread.currentThread().setContextClassLoader( cl );\n    }\n  }\n\n  @Override public S3Details prepare( S3Details s3Details ) throws KettleException {\n    VariableSpace space = getSpace( s3Details );\n    if ( s3Details.getAuthType().equals( CREDENTIALS_FILE ) ) {\n      String credentialsFilePath = getVar( s3Details.getCredentialsFilePath(), space );\n      if ( credentialsFilePath != null ) {\n        try ( BufferedReader reader = Files.newBufferedReader( Paths.get( credentialsFilePath ) ) ) {\n          StringBuilder builder = new StringBuilder();\n          String currentLine;\n          while ( ( currentLine = reader.readLine() ) != null ) {\n            builder.append( currentLine ).append( \"\\n\" );\n          }\n          s3Details.setCredentialsFile( builder.toString() );\n        } catch ( IOException e ) {\n          throw new KettleException( \"Could not read file \", e );\n        }\n      }\n    }\n    return s3Details;\n  }\n\n  @Override\n  public FileObject getDirectFile( Bowl bowl, S3Details s3Conn, String path ) throws KettleFileException {\n    if ( !S3FileProvider.SCHEME.equals( s3Conn.getType() ) ) {\n      return null;\n    }\n    FileSystemOptions fsopts = getOpts( s3Conn );\n    S3CommonFileSystemConfigBuilder builder = new S3CommonFileSystemConfigBuilder( fsopts );\n    // Disable \"Use Defaults\" so we don't call back into ConnectionManager for the default S3 connection\n    builder.setUseDefaults( false );\n    fsopts = builder.getFileSystemOptions();\n\n    String uri = S3FileProvider.SCHEME + \"://\" + path;","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/s3-vfs/core/src/main/java/org/pentaho/amazon/s3/provider/S3Provider.java#L182-L218","documentation":"S3Provider.prepare() reads an optional credentials file line by line and stores its contents on S3VfsDetails. If the file cannot be read, it wraps the IOException in a KettleException with the message 'Could not read file '. This is a fail-fast configuration error: the S3 connection cannot be prepared without the credentials file.","triggerScenarios":"Calling prepare() when the credentials-file path set on s3Details points to a nonexistent, unreadable, locked, or permission-denied file, or when the BufferedReader/FileInputStream construction throws IOException.","commonSituations":"Typo in the credentials file path in the S3 VFS connection dialog, file deployed on a different node, file mounted with wrong permissions, or file deleted between configuration and runtime.","solutions":["Check the credentials-file path configured on the S3 connection and fix typos.","Verify the file exists and is readable by the user running Pentaho (chmod/chown).","Use an absolute path rather than a relative one, since the working directory varies.","Alternatively configure access/secret keys directly instead of a credentials file.","Catch KettleException at the call site to surface a user-friendly message."],"exampleFix":"// before\ns3Details.setCredentialsFile( \"/opt/creds.txt\" );\n// after\nFile f = new File( \"/opt/creds.txt\" );\nif ( !f.isFile() || !f.canRead() ) {\n  throw new KettleException( \"Credentials file missing or unreadable: \" + f.getAbsolutePath() );\n}","handlingStrategy":"validation","validationCode":"java.io.File f = new java.io.File( credentialsFilePath );\nif ( credentialsFilePath == null || credentialsFilePath.isEmpty() )\n  throw new IllegalArgumentException( \"credentials file path not set\" );\nif ( !f.isFile() ) throw new java.io.FileNotFoundException( f.getAbsolutePath() );\nif ( !f.canRead() ) throw new java.io.IOException( \"not readable: \" + f.getAbsolutePath() );","typeGuard":null,"tryCatchPattern":"try {\n  provider.prepare();\n} catch ( KettleException e ) {\n  // e.getCause() is the IOException from reading the credentials file\n  throw new KettleException( \"Fix the credentials-file path on the S3 connection: \" + e.getCause().getMessage(), e );\n}","preventionTips":["Store credentials-file paths as absolute paths in connection metadata","Check file readability at job startup with a pre-flight validation step","Keep credentials files on shared storage accessible to all cluster nodes","Prefer direct key configuration or a secrets manager over flat files"],"tags":["io","file-read","configuration","kettle"],"backgroundTag":"file-read-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}