{"record":{"id":"92e560134cda4c72","repo":"apache/hadoop","slug":"privilegedactionexception-with-no-underlying-cause","errorCode":null,"errorMessage":"PrivilegedActionException with no underlying cause. UGI [\" + this + \"]: \" + pae","messagePattern":"PrivilegedActionException with no underlying cause\\. UGI \\[\" \\+ this \\+ \"\\]: \" \\+ pae","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java","lineNumber":1962,"sourceCode":"   * @return the value from the run method\n   * @throws IOException if the action throws an IOException\n   * @throws Error if the action throws an Error\n   * @throws RuntimeException if the action throws a RuntimeException\n   * @throws InterruptedException if the action throws an InterruptedException\n   * @throws UndeclaredThrowableException if the action throws something else\n   */\n  @InterfaceAudience.Public\n  @InterfaceStability.Evolving\n  public <T> T doAs(PrivilegedExceptionAction<T> action\n                    ) throws IOException, InterruptedException {\n    try {\n      tracePrivilegedAction(action);\n      return SubjectUtil.doAs(subject, action);\n    } catch (PrivilegedActionException pae) {\n      Throwable cause = pae.getCause();\n      LOG.debug(\"PrivilegedActionException as: {}\", this, cause);\n      if (cause == null) {\n        throw new RuntimeException(\"PrivilegedActionException with no \" +\n                \"underlying cause. UGI [\" + this + \"]\" +\": \" + pae, pae);\n      } else if (cause instanceof IOException) {\n        throw (IOException) cause;\n      } else if (cause instanceof Error) {\n        throw (Error) cause;\n      } else if (cause instanceof RuntimeException) {\n        throw (RuntimeException) cause;\n      } else if (cause instanceof InterruptedException) {\n        throw (InterruptedException) cause;\n      } else {\n        throw new UndeclaredThrowableException(cause);\n      }\n    }\n  }\n\n  private void tracePrivilegedAction(Object action) {\n    if (LOG.isTraceEnabled()) {\n      // would be nice if action included a descriptive toString()","sourceCodeStart":1944,"sourceCodeEnd":1980,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java#L1944-L1980","documentation":"UGI.doAs unwraps PrivilegedActionException and rethrows its cause with the original type. In the rare case the PAE carries no cause (getCause() null), it wraps the PAE itself in this RuntimeException rather than losing it. The real diagnostic value is the PrivilegedActionException in the message, not the wrapper.","triggerScenarios":"Subject.doAs throwing a PrivilegedActionException constructed without a cause - unusual JVM/JDK behavior, custom doAs implementations, or exceptions reconstructed via deserialization inside the action.","commonSituations":"Almost never seen in practice; when it appears it usually accompanies exotic classloading or a custom SecurityManager/Subject doAs replacement. Most sightings are actually downstream symptoms logged by RPC layers calling doAs.","solutions":["Read the full message: the PAE's toString identifies the action and where it originated","Catch Throwable inside the PrivilegedExceptionAction and log it there, so the cause never depends on PAE wrapping","If reproducible on one JDK only, compare JVM versions/vendor; file the mismatch rather than working around it blindly"],"exampleFix":"// before\nugi.doAs((PrivilegedExceptionAction<Void>) () -> { ...; return null; });\n// after: capture diagnostics inside the action\nugi.doAs((PrivilegedExceptionAction<Void>) () -> {\n  try { ...; return null; }\n  catch (Throwable t) { LOG.error(\"action failed\", t); throw t; }\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return ugi.doAs(action);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null\n      && e.getMessage().contains(\"no underlying cause\")) {\n    // inspect the PrivilegedActionException embedded in the message\n    LOG.error(\"doAs lost the underlying cause: {}\", e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["Catch and log Throwable inside the PrivilegedExceptionAction itself","Do not rely on PAE cause-chaining for diagnostics","Pin JVM versions across the fleet so rare doAs behaviors are reproducible"],"tags":["hadoop","ugi","doas","privileged-action"],"backgroundTag":"lost-exception-cause","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}