{"record":{"id":"929a063a8a3a09f2","repo":"pentaho/pentaho-kettle","slug":"auth-error","errorCode":null,"errorMessage":"Auth error","messagePattern":"Auth error","errorType":"exception","errorClass":"RepositoryClientException","httpStatus":401,"severity":"error","filePath":"plugins/repo-vfs/repo-vfs-ws/src/main/java/org/pentaho/di/plugins/repovfs/ws/repo/RepositoryClient.java","lineNumber":281,"sourceCode":"      default:\n        throwOnError( response );\n        // unreachable\n        return Optional.empty();\n    }\n  }\n\n  private static String encodePath( String[] path ) {\n    return \":\" + Stream.of( path ).map( Encode::forUriComponent ).collect( Collectors.joining( \":\" ) );\n  }\n\n  private void throwOnError( final Response response ) throws RepositoryClientException {\n    final int status = response.getStatus();\n\n    if ( status != HttpStatus.SC_OK ) {\n      if ( status == HttpStatus.SC_MOVED_TEMPORARILY\n        || status == HttpStatus.SC_FORBIDDEN\n        || status == HttpStatus.SC_UNAUTHORIZED ) {\n        throw new RepositoryClientException( \"Auth error\" );\n      } else {\n        String errMsg;\n        try {\n          errMsg = response.readEntity( String.class );\n        } catch ( Exception e ) {\n          errMsg = \"Unable to get error response entity\";\n        }\n        throw new RepositoryClientException( errMsg + \" status:\" + status );\n      }\n    }\n  }\n\n  private static String encodePath( String path ) {\n    String repoEncoded = RepositoryPathEncoder.encodeRepositoryPath( path );\n    return Encode.forUriComponent( repoEncoded );\n  }\n}\n","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/repo-vfs/repo-vfs-ws/src/main/java/org/pentaho/di/plugins/repovfs/ws/repo/RepositoryClient.java#L263-L299","documentation":"throwOnError() centralizes response checking and throws RepositoryClientException(\"Auth error\") when the HTTP status is 302 (moved temporarily), 403 (forbidden), or 401 (unauthorized). In this service those statuses indicate the caller was redirected to a login page or denied, i.e. the session is not authenticated.","triggerScenarios":"Calling writeData, moveTo, rename, or getFileInfo when the session cookie is missing/expired, credentials are wrong, or the server redirects unauthenticated requests to the login page.","commonSituations":"Long-running jobs whose session expired mid-run; not calling login before API operations; incorrect username/password; server security changes (e.g. requiring new auth headers); proxy stripping cookies.","solutions":["Re-authenticate (perform login to obtain a fresh session cookie) and retry the operation","Verify username/password/tenant configuration used to build the authentication","Ensure CookieHandler/CookieManager is enabled so session cookies persist across requests (the constructor sets a default CookieManager)","Check that the server is not redirecting (302) to SSO/login - configure the client for the deployed security model"],"exampleFix":"// before\nRepositoryClient client = new RepositoryClient( cfg, url, auth ); // never logged in\nclient.writeData( path, data ); // Auth error\n// after\nRepositoryClient client = new RepositoryClient( cfg, url, auth );\nclient.login(); // establish session cookie\nclient.writeData( path, data );","handlingStrategy":"retry","validationCode":"// Ensure a session exists before API calls\nif ( !client.isLoggedIn() ) { client.login(); }","typeGuard":null,"tryCatchPattern":"try {\n  client.writeData( path, data );\n} catch ( RepositoryClientException e ) {\n  if ( \"Auth error\".equals( e.getMessage() ) ) {\n    client.login();          // refresh session cookie\n    client.writeData( path, data ); // retry once\n  }\n}","preventionTips":["Always login before the first API call of a session","Re-login proactively for long-running jobs (session expiry)","Keep the CookieManager default installed so session cookies persist","Verify credentials and the server's SSO/redirect (302) configuration"],"tags":["http","authentication","redirect","rest"],"backgroundTag":"authentication-required","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"}